📄 classresolver.c
字号:
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 + -