📄 classresolver.c
字号:
super_itable_count * ITEM_SIZE); icount += super_itable_count; } for (i = 0; i < (int)(cbImplementsCount(cb)); i++) { /* Add the interfaces that we implement, either directly, or * because those interfaces implement other interfaces. */ int interface_index = cbImplements(cb)[i]; icb = constant_pool[interface_index].clazz; memcpy(&this_itable->itable[icount], &cbIntfMethodTable(icb)->itable[0], cbIntfMethodTable(icb)->icount * ITEM_SIZE); icount += cbIntfMethodTable(icb)->icount; } sysAssert(!isInterface || super_itable_count == 0); /* Delete duplicates from the table. This is very rare, so it can * be quite inefficient. */ for (i = (isInterface ? 1 : super_itable_count); i < icount; i++) { icb = this_itable->itable[i].classdescriptor; for (j = 0; j < i; j++) { if (icb == this_itable->itable[j].classdescriptor) { /* We have an overlap. Item i is a duplicate. Delete from * the table */ for (k = i + 1; k < icount; k++) this_itable->itable[k - 1] = this_itable->itable[k]; icount--; i--; /* Reconsider this entry! */ break; } } } this_itable->icount = icount; if (isInterface || cbIsAbstract(cb)) { /* Nothing more to do for interfaces or abstract classes */ return NULL; } /* For each additional interface . . . */ for (i = super_itable_count; i < icount; i++) { /* The table length is the number of interface methods */ ClassClass *intfi = this_itable->itable[i].classdescriptor; int intfi_count = cbMethodsCount(intfi); unsigned long *offsets = (unsigned long *)mallocSpace; mallocSpace += intfi_count * sizeof(unsigned long); sysAssert(mallocSpace <= mallocSpaceEnd); this_itable->itable[i].offsets = offsets; /* Look at each interface method */ for (j = 0; j < intfi_count; j++) { struct methodblock *imb = cbMethods(intfi) + j; if ((imb->fb.access & ACC_STATIC) != 0) { sysAssert(!strcmp(imb->fb.name, "<clinit>")); offsets[j] = 0; } else { /* Find the class method that implements the interface * method */ unsigned ID = imb->fb.ID; struct methodblock **mbt = cbMethodTable(cb)->methods; for (k = cbMethodTableSize(cb) - 1; k >= 0; --k) { struct methodblock *mb = mbt[k]; if (mb != NULL && mb->fb.ID == ID && IsPublic(mb->fb.access)) { offsets[j] = mb->fb.u.offset; break; } } /* if (k == -1) { *detail = "Unimplemented interface method"; return JAVAPKG "IncompatibleClassChangeError"; } */ } } } return NULL; }}char *InitializeClass(ClassClass * cb, char **detail) { char *result; monitorEnter(obj_monitor(cb)); result = Locked_InitializeClass(cb, detail); monitorExit(obj_monitor(cb)); return result;}char *ResolveClass(ClassClass *cb, char **detail) { char *result; if (CCIs(cb, Resolved)) return 0; result = LinkClass(cb, detail); if (result == 0) { if (!RunClinit(cb)) { result = JAVAPKG "ExceptionInInitializerError"; *detail = cbName(cb); } } return result;}char *LinkClass(ClassClass *cb, char **detail){ char *result; if (CCIs(cb, Linked)) return 0; monitorEnter(obj_monitor(cb)); result = Locked_LinkClass(cb, detail); monitorExit(obj_monitor(cb)); return result;}/* * Detect class circularities from InitializeClass() */static voidpushSeen(ExecEnv *ee, struct seenclass *seen){ struct seenclass *prev = ee->seenclasses.next; ee->seenclasses.next = seen; seen->next = prev;}static voidpopSeen(ExecEnv *ee, struct seenclass *seen){ if (seen != ee->seenclasses.next) /* paranoia */ panic("popSeen: corrupt seen class stack"); ee->seenclasses.next = ee->seenclasses.next->next;}static bool_tcheckSeen(ExecEnv *ee, ClassClass *cb){ struct seenclass *seen = ee->seenclasses.next; while (seen) { if (cb == seen->cb) return TRUE; seen = seen->next; } return FALSE;}static char *Locked_InitializeClass(ClassClass * cb, char **detail){ ClassClass *super = 0; char *ret = 0; bool_t noLoader; int i; char buff[BUFSIZ]; char *nativeName = &buff[0]; if (CCIs(cb, Initialized)) return NULL;#ifndef TRIMMED if (verbose) jio_fprintf(stderr, "[Initializing %s]\n", cbName(cb));#endif noLoader = (cbLoader(cb) == 0); if (cbFieldsCount(cb) > 2000) { return JAVAPKG "ClassFormatError"; } if ((strcmp(cbName(cb), CLS_RESLV_INIT_CLASS) == 0) && noLoader) { /* Temporarily disable class circularity checks */ ExecEnv *ee = EE(); struct seenclass *save = ee->seenclasses.next; ee->seenclasses.next = NULL; /* Note: don't bother restoring on (fatal) error during bootstrap */ classJavaLangClass = cb; MakeClassSticky(cb); classJavaLangString = FindStickySystemClass(NULL, JAVAPKG "String", TRUE); if (classJavaLangString == 0) { *detail = JAVAPKG "String"; return JAVAPKG "NoClassDefFoundError"; }/* classJavaLangThreadDeath = FindStickySystemClass(NULL, JAVAPKG "ThreadDeath", TRUE); if (classJavaLangThreadDeath == 0) { *detail = JAVAPKG "ThreadDeath"; return JAVAPKG "NoClassDefFoundError"; } */ classJavaLangThrowable = FindStickySystemClass(NULL, JAVAPKG "Throwable", TRUE); if (classJavaLangThrowable == 0) { *detail = JAVAPKG "Throwable"; return JAVAPKG "NoClassDefFoundError"; } /* classJavaLangException = FindStickySystemClass(NULL, JAVAPKG "Exception", TRUE); if (classJavaLangException == 0) { *detail = JAVAPKG "Exception"; return JAVAPKG "NoClassDefFoundError"; } classJavaLangError = FindStickySystemClass(NULL, JAVAPKG "Error", TRUE); if (classJavaLangError == 0) { *detail = JAVAPKG "Error"; return JAVAPKG "NoClassDefFoundError"; } classJavaLangRuntimeException = FindStickySystemClass(NULL, JAVAPKG "RuntimeException", TRUE); if (classJavaLangRuntimeException == 0) { *detail = JAVAPKG "RuntimeException"; return JAVAPKG "NoClassDefFoundError"; } interfaceJavaLangCloneable = FindStickySystemClass(NULL, JAVAPKG "Cloneable", TRUE); if (interfaceJavaLangCloneable == 0) { *detail = JAVAPKG "Cloneable"; return JAVAPKG "NoClassDefFoundError"; } interfaceJavaIoSerializable = FindStickySystemClass(NULL, "java/io/Serializable", TRUE); if (interfaceJavaIoSerializable == 0) { *detail = "java/io/Serializable"; return JAVAPKG "NoClassDefFoundError"; }*/ /* Restore stack for class circularity checks */ ee->seenclasses.next = save; } else if ((strcmp(cbName(cb), CLS_RESLV_INIT_OBJECT) == 0) && noLoader){ classJavaLangObject = cb; MakeClassSticky(classJavaLangObject); } if (noLoader) { char *name = cbName(cb); if (strcmp(name, CLS_RESLV_INIT_REF) == 0) { CCSet(cb, SoftRef); } if (strncmp(name, "java/", 5) || strncmp(name, "sun/", 4)) { CCSet(cb, SysLock); } } if (cbSuperclass(cb) == NULL) { if (cbSuperName(cb)) { /* Check for class definition circularities */ ExecEnv *ee = EE(); struct seenclass this[1]; if (checkSeen(ee, cb)) { *detail = cbName(cb); CCSet(cb, Error); return JAVAPKG "ClassCircularityError"; } this->cb = cb; this->next = NULL; pushSeen(ee, this); /* Conversion for Japanese file names */ utf2native(cbSuperName(cb), nativeName, BUFSIZ); super = FindClassFromClass(ee, nativeName, FALSE, cb); popSeen(ee, this); if (super != NULL) { sysAssert(CCIs(super, Initialized)); /* Don't allow a class to have a superclass it can't access */ if (!VerifyClassAccess(cb, super, FALSE)) { super = NULL; } } if (super != NULL) { cbSuperclass(cb) = cbHandle(super); if (CCIs(super, SoftRef)) CCSet(cb, SoftRef); } else { ret = JAVAPKG "NoClassDefFoundError"; *detail = cbSuperName(cb); cbSuperclass(cb) = NULL; CCSet(cb, Error); } } else if (cb == classJavaLangObject) { cbSuperclass(cb) = 0; } else { *detail = cbName(cb); return JAVAPKG "ClassFormatException"; } } for (i = 0; i < (int)(cbImplementsCount(cb)); i++) { /* Be very careful, since not verified yet. . . */ int interface_index = cbImplements(cb)[i]; cp_item_type *constant_pool = cbConstantPool(cb); unsigned char *type_table = constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type; ClassClass *icb; int nconstants = cbConstantPoolCount(cb); int iname_index; char *iname; if (interface_index <= 0 || interface_index >= nconstants || type_table[interface_index] != CONSTANT_Class || !(iname_index = constant_pool[interface_index].i) || iname_index <= 0 || iname_index >= nconstants || type_table[iname_index] != (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED)) { *detail = "Bad interface index"; return JAVAPKG "ClassFormatError"; } iname = constant_pool[iname_index].cp; if (iname == NULL || !IsLegalClassname(iname, FALSE)) { *detail = "Bad interface name"; return JAVAPKG "ClassFormatError"; } { ExecEnv *ee = EE(); struct seenclass this[1]; if (checkSeen(ee, cb)) { *detail = cbName(cb); CCSet(cb, Error); return JAVAPKG "ClassCircularityError"; } this->cb = cb; this->next = NULL; pushSeen(ee, this); icb = FindClassFromClass(ee, iname, FALSE, cb); popSeen(ee, this); if (icb) { constant_pool[interface_index].clazz = icb; type_table[interface_index] |= CONSTANT_POOL_ENTRY_RESOLVED; } else { *detail = iname; CCSet(cb, Error); return JAVAPKG "NoClassDefFoundError"; } } } CCSet(cb, Initialized); /* Make sure we know what classJavaLangClass is, and that it's method table * is filled in. */ if (classJavaLangClass == 0) { classJavaLangClass = FindClassFromClass(0, CLS_RESLV_INIT_CLASS, TRUE, cb); if (classJavaLangClass == 0) { return JAVAPKG "NoClassDefFoundError"; } } /* The following may not do anything useful if classJavaLangClass hasn't * been completely resolved. But we clean up in ResolveClass */ cbHandle(cb)->methods = cbMethodTable(classJavaLangClass); return ret;}static char *Locked_LinkClass(ClassClass * cb, char **detail){ ClassClass *super = 0; unsigned slot = 0; char *ret = 0; int i; if (CCIs(cb, Error)) { *detail = cbName(cb); return JAVAPKG "NoClassDefFoundError"; } sysAssert(CCIs(cb, Initialized)); if (CCIs(cb, Linked)) { return NULL; } if (cbSuperclass(cb)) { /* If this object has a superclass. . . */ super = cbSuperclass(cb); if (!CCIs(super, Linked)) { if ((ret = LinkClass(super, detail)) != 0) { CCSet(cb, Error); return ret; } } sysAssert(CCIs(super, Linked)); slot = cbInstanceSize(super); } for (i = 0; i < (int)(cbImplementsCount(cb)); i++) { int interface_index = cbImplements(cb)[i]; cp_item_type *constant_pool = cbConstantPool(cb); ClassClass *icb; icb = constant_pool[interface_index].clazz; if (!CCIs(icb, Linked)) { if ((ret = LinkClass(icb, detail)) != 0) { CCSet(cb, Error); return ret; } } } sysAssert(!CCIs(cb, Error)); sysAssert(!CCIs(cb, Linked));#ifndef TRIMMED if (verbose) jio_fprintf(stderr, "[Resolving %s]\n", cbName(cb));#endif cbInstanceSize(cb) = -1; if ((ret = ResolveFields(cb, slot))) { /* May return "InternalError" */ *detail = cbName(cb); CCSet(cb, Error); return ret; } if ((ret = ResolveMethods(cb))) { /* May return "OutOfMemoryError" or "InternalError" */ *detail = cbName(cb); CCSet(cb, Error); return ret; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -