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

📄 classresolver.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#)classresolver.c	1.19 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: class resolver.c. * FILE:      classresolver.c * OVERVIEW:  Routines for loading and resolving class definitions. *            These routines should not be depending upon the interpreter *            or the garbage collector. * AUTHOR:    Sheng Liang, Sun Microsystems, Inc. *            Modifications for CLDC compliance checks, *            Tasneem Sayeed, Sun Microsystems *            Frank Yellin, Sun Microsystems *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <ctype.h>#include <string.h>#include <sys/types.h>#include <fcntl.h>#include <sys/stat.h>#include <stdlib.h>#include <oobj.h>#include <tree.h>#include <signature.h>#include <path.h>#include <sys_api.h>#include <convert_md.h>/*========================================================================= * Globals and extern declarations *=======================================================================*/ClassClass *classJavaLangObject;ClassClass *classJavaLangClass = 0;ClassClass *classJavaLangString;ClassClass *classJavaLangThrowable;ClassClass *classJavaLangError;ClassClass *classJavaLangException;ClassClass *classJavaLangRuntimeException;ClassClass *classJavaLangThreadDeath;ClassClass *interfaceJavaLangCloneable;ClassClass *interfaceJavaIoSerializable;bool_t inline_jsr_on = TRUE;static bool_t RunClinit(ClassClass * cb);static ClassClass *InitializeAndResolveClass(ClassClass *cb, bool_t resolve);static char *Locked_InitializeClass(ClassClass * cb, char **detail);static char *Locked_LinkClass(ClassClass * cb, char **detail);char * LinkClass(ClassClass *cb, char **detail);static ClassClass *FindLoadedClass(char *name,				   struct Hjava_lang_ClassLoader *loader);static ClassClass *Locked_FindArrayClassFromClass(struct execenv *ee, 						  char *name, 						  ClassClass *from);static void InitPrimitiveClasses();/* An Explanation of Class-related Locks * * There are two global locks related to class loading: * * LOADCLASS_LOCK: ensures that only one thread is loading a class at * a given time. This eliminates the possibility of two threads loading * classes with the same name and same loader. * * BINCLASS_LOCK: ensures that only one thread is updating the global * class table (binclasses). This lock is also grabbed by the GC to ensure * that the GC always sees a valid global class table state. * * In addition, each class may have its own associated locks that are * created with monitorEnter(). ResolveClass, for example, need to * first grab this lock to ensure that the class is resolved only by * one thread, rather than simultaneously by multiple threads. */sys_mon_t *_loadclass_lock;sys_mon_t *_binclass_lock;static struct fieldblock **addslots(struct fieldblock ** fb, ClassClass * cb){    long n = cbFieldsCount(cb);    struct fieldblock *sfb = cbFields(cb);    if (cbSuperclass(cb))	fb = addslots(fb, cbSuperclass(cb));    while (--n >= 0) {	*fb++ = sfb;	sfb++;    }    return fb;}intLocked_makeslottable(ClassClass * clb){    ClassClass *sclb;    int         nslots = 0;    if (cbSlotTable(clb)) {	return SYS_OK;    }    sclb = clb;    while (sclb) {	long        n = cbFieldsCount(sclb);	struct fieldblock *fb = cbFields(sclb);	while (--n >= 0) {	    nslots++;	    fb++;	}	if (cbSuperclass(sclb) == 0) {	    break;	}	sclb = cbSuperclass(sclb);    }    cbSlotTableSize(clb) = nslots;    if (nslots == 0) {	nslots++;    }    cbSlotTable(clb) = (struct fieldblock **)	sysMalloc(nslots * sizeof(struct fieldblock *));    if (cbSlotTable(clb) == 0) {	return SYS_NOMEM;    }    addslots(cbSlotTable(clb), clb);    return SYS_OK;}intmakeslottable(ClassClass * clb){    int result;    LOADCLASS_LOCK();    result = Locked_makeslottable(clb);    LOADCLASS_UNLOCK();    return result;}#if 0static char *copyclassname(char *src, char *dst){    sysAssert(*src == SIGNATURE_CLASS);    src++;    while (*src && *src != SIGNATURE_ENDCLASS)	*dst++ = *src++;    *dst = 0;    return src;}#endifstatic char *ResolveFields(ClassClass *cb, unsigned slot){    struct fieldblock *fb;    int size;    fb = cbFields(cb);    for (size = 0; size < (int) cbFieldsCount(cb); size++, fb++) {	char *signature = fieldsig(fb);	int size = (((signature[0] == SIGNATURE_LONG || 		      signature[0] == SIGNATURE_DOUBLE)) ? 2 : 1);	fb->ID = NameAndTypeToHash(fb->name, signature);	if (fb->access & ACC_STATIC) {	    /* Do nothing.  Handled when the class is loaded. */	} else {	    fb->u.offset = slot;	    slot += size * sizeof(OBJECT);	}#ifdef UNUSED	if ((fb->access & (ACC_STATIC | ACC_TRANSIENT)) == 0) {	    for (s = fieldname(fb); (c = *s++) != 0;)		thishash = thishash * 7 + c;	    for (s = fieldsig(fb); (c = *s++) != 0;)		thishash = thishash * 7 + c;	}#endif    }    if (slot > 65535) {        return "java/lang/InternalError";    }    cbInstanceSize(cb) = slot;#ifdef UNUSED    cbThisHash(cb) = thishash;    if (cbSuperclass(cb))	cbTotalHash(cb) = thishash - cbTotalHash(unhand(cbSuperclass(cb)));    else        cbTotalHash(cb) = thishash;    if (cbTotalHash(cb) < N_TYPECODES)	cbTotalHash(cb) += N_TYPECODES;#endif    return NULL;}static char *ResolveMethods(ClassClass *cb){    struct methodblock *mb;    int size;    struct methodtable *new_table;    struct methodblock **super_methods;    int mslot, super_methods_count;    void *ptr;    static unsigned finalizerID = 0;        if (finalizerID == 0)	finalizerID = NameAndTypeToHash(FINALIZER_METHOD_NAME,					FINALIZER_METHOD_SIGNATURE);    mb = cbMethods(cb);    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {	mb->fb.ID = NameAndTypeToHash(mb->fb.name, mb->fb.signature);	mb->fb.u.offset = 0;	mb->invoker = 0;    }    if (cbIsInterface(cb)) { 	/* We don't really need to built a method table for interfaces. */	cbMethodTable(cb) = NULL;	cbMethodTableSize(cb) = 0;	mb = cbMethods(cb);	/* Each method's offset is its index in the interface */	for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {	    mb->fb.u.offset = size;	}	return NULL;    }    if (cbSuperclass(cb) != NULL) { 	ClassClass *super = cbSuperclass(cb);	mslot = cbMethodTableSize(super);	super_methods = cbMethodTable(super)->methods;        super_methods_count = cbMethodTableSize(super);	/* Inherit one's parent's finalizer, if it has one */	cbFinalizer(cb) = cbFinalizer(cbSuperclass(cb));    } else { 	mslot = 1;	super_methods = NULL;	super_methods_count = 0;	cbFinalizer(cb) = NULL;    }    mb = cbMethods(cb);    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {	unsigned long ID = mb->fb.ID;	struct methodblock **super_methods_p;	int count;	if ((mb->fb.access & ACC_STATIC) || (mb->fb.access & ACC_PRIVATE))	    continue;	if (strcmp(mb->fb.name, "<init>") == 0)	    continue;	/* If this item has its own finalizer method, grab it */	if (mb->fb.ID == finalizerID) {	    if (no_finalizers) {		panic("finalize methods should not appear");	    }	    cbFinalizer(cb) = mb;	}	for (super_methods_p = super_methods, count = super_methods_count;	       count > 0;	       super_methods_p++, count--) {	    if ((*super_methods_p != NULL) && ((*super_methods_p)->fb.ID == ID)) { 	      /* Private methods are not inherited outside of the class. */	        if ((*super_methods_p)->fb.access & ACC_PRIVATE)		  continue;	      /* Package-private methods are not inherited outside of the		 package. */	        if (((*super_methods_p)->fb.access & ACC_PROTECTED) ||		    ((*super_methods_p)->fb.access & ACC_PUBLIC) ||		    IsSameClassPackage((*super_methods_p)->fb.clazz, cb)) {		    mb->fb.u.offset = (*super_methods_p)->fb.u.offset;		    break;		} 	      /*		jio_fprintf(stderr, "!!!%s.%s\n", cbName(cb), mb->fb.name);		*/	    }	}	if (mb->fb.u.offset == 0) { 	    mb->fb.u.offset = mslot;	    mslot++;	}    }    if (mslot > 65535) {        return "java/lang/InternalError";    }    /*     *	This should be the only place that method tables are     *	allocated.  We allocate more than we need here and mask the     *	resulting pointer because the methodtable pointer field in     *	object handles is overloaded and sometimes hold array types     *	and array lengths.  We must ensure that method table pointers     *	are allocated on an appropriate boundary so we don't lose any     *	address bits when we mask off the type portion of the pointer.     */    ptr = sysMalloc(sizeof(struct methodtable)		       + (mslot - 1)* sizeof(struct methodblock *)		       + FLAG_MASK);    if (ptr == NULL) {	CCSet(cb, Error);	return JAVAPKG "OutOfMemoryError";    }    cbMethodTableMem(cb) = ptr;    new_table = (struct methodtable *)((((long)ptr) + FLAG_MASK) & LENGTH_MASK);    new_table->classdescriptor = cb;    memset((char *)new_table->methods, 0, mslot * sizeof(struct methodblock *));    if (super_methods) 	memcpy((char *) new_table->methods,	       (char *) super_methods,	       super_methods_count * sizeof(struct methodblock *));    mb = cbMethods(cb);    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {	int offset = (int)mb->fb.u.offset;	if (offset > 0) { 	    sysAssert(offset < mslot);	    mt_slot(new_table, offset) = mb;	}    }    cbMethodTable(cb) = new_table;    cbMethodTableSize(cb) = mslot;    return NULL;}static char *ResolveInterfaces(ClassClass *cb, char **detail){    const int ITEM_SIZE =  sizeof(cbIntfMethodTable(cb)->itable[0]);    bool_t isInterface = cbIsInterface(cb);    if (cbImplementsCount(cb) == 0 && !isInterface) {	/* classes that don't implement their own interfaces can just inherit	 * their parents imethodtable. */	if (cb == classJavaLangObject) {	    /* We can preinitialize the imethodtable of java.lang.Object */	    static struct imethodtable t = { 0 };	    cbIntfMethodTable(cb) = &t;	} else { 	    ClassClass *super = cbSuperclass(cb);	    cbIntfMethodTable(cb) = cbIntfMethodTable(super);	} 	return NULL;    } else { 	cp_item_type *constant_pool = cbConstantPool(cb);	ClassClass *super = cbSuperclass(cb);	unsigned char *mallocSpace, *mallocSpaceEnd;	ClassClass *icb;	/* temporary */	struct imethodtable *super_itable = cbIntfMethodTable(super);	struct imethodtable *this_itable = NULL;	int super_itable_count = super_itable->icount;	int i, j, k, icount, mcount;		/* Resolve all the interfaces that this class implements, and 	 * make sure that they all really are interfaces 	 *	 * icount will total all the interfaces that this class implements,	 *    (include interfaces implemented by our superclass, and by 	 *    interfaces that we implement.)	 * mcount will total the total amount of space (in sizeof(long)) for 	 *    which we'll have to allocate space for in the offsets table.	 */	icount = super_itable_count + (isInterface ? 1 : 0);	mcount = 0;	for (i = 0; i < (int)(cbImplementsCount(cb)); i++) {	    int interface_index = cbImplements(cb)[i];	    struct imethodtable *sub_itable;	    icb = constant_pool[interface_index].clazz;	    if (!cbIsInterface(icb)) {	        *detail = "Implementing class";		return JAVAPKG "IncompatibleClassChangeError";	    }	    sub_itable = cbIntfMethodTable(icb);	    icount += sub_itable->icount;	    if (!isInterface) 		for (j = sub_itable->icount; --j >= 0; ) 		    mcount += cbMethodsCount(sub_itable->itable[j].classdescriptor);	}	{ 	    int this_itable_size = 		offsetof(struct imethodtable, itable) + icount * ITEM_SIZE;	    int offsets_size = mcount * sizeof(unsigned long);	    mallocSpace = sysMalloc(this_itable_size + offsets_size);	    if (mallocSpace == NULL) { 		return JAVAPKG "OutOfMemoryError";	    }	    mallocSpaceEnd = mallocSpace + this_itable_size + offsets_size;	    this_itable = (struct imethodtable *)mallocSpace;	    mallocSpace += this_itable_size;	    sysAssert(mallocSpace <= mallocSpaceEnd);	}		cbIntfMethodTable(cb) = this_itable;	/* Start filling in the table. */	icount = 0;	if (isInterface) {	    this_itable->itable[icount].classdescriptor = cb;	    this_itable->itable[icount].offsets = NULL;		    icount++;	}	if (super_itable_count > 0) { 	    /* We can copy our superclass's offset table.  The offsets	       will stay the same.  */	    memcpy(&this_itable->itable[icount], 		   &super_itable->itable[0], 

⌨️ 快捷键说明

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