classmethod.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 2,775 行 · 第 1/5 页
C
2,775 行
DBG(STATICINIT, dprintf("using callMethodA\n"); ) callMethodA(meth, METHOD_INDIRECTMETHOD(meth), 0, 0, 0, 1); } lockClass(class); class->processingThread = 0; if (exc != 0) { if( soft_instanceof(javaLangException, exc) ) { /* this is special-cased in throwError */ einfo->type = (KERR_INITIALIZER_ERROR | KERR_NO_CLASS_FOUND); einfo->throwable = exc; } else { /* Should be an error... */ einfo->type = (KERR_RETHROW | KERR_NO_CLASS_FOUND); einfo->throwable = exc; } /* * we return false here because COMPLETE fails */ success = false; SET_CLASS_STATE(CSTATE_FAILED); } else { SET_CLASS_STATE(CSTATE_COMPLETE); } /* Since we'll never run this again we might as well * lose it now. However, if there was an exception, keep * it so the stack trace doesn't lose the <clinit> frame. */#if defined(TRANSLATOR) && (defined (MD_UNREGISTER_JIT_EXCEPTION_INFO) || defined (JIT3))#if defined(MD_UNREGISTER_JIT_EXCEPTION_INFO) if (exc == 0) { MD_UNREGISTER_JIT_EXCEPTION_INFO (meth->c.ncode.ncode_start, METHOD_NATIVECODE(meth), meth->c.ncode.ncode_end); }#endif#endif if (#if defined(JIT3) (exc == 0) &&#endif#if defined(KAFFE_XPROFILER) !xProfFlag &&#endif 1) { METHOD_NATIVECODE(meth) = 0; KFREE(meth->c.ncode.ncode_start); meth->c.ncode.ncode_start = 0; meth->c.ncode.ncode_end = 0; } }done: /* If anything ever goes wrong with this class, we declare it dead * and will respond with NoClassDefFoundErrors to any future attempts * to access that class. * NB: this does not include when a static initializer failed. */ if (success == false && class->state != CSTATE_FAILED) { SET_CLASS_STATE(CSTATE_FAILED); if( ce->state != NMS_DONE ) { setClassMappingState(ce, NMS_EMPTY); } } /* wake up any waiting threads */ broadcastOnClass(class); unlockClass(class);DBG(RESERROR, for (i = 0; i < depth; dprintf(" "), i++); depth--; dprintf("%p leaving process class %s -> %s\n", jthread_current(), class->name->data, success ? "success" : "failure"); ) return (success);}static intexpandMethods(Hjava_lang_Class *cl, Method *imeth, errorInfo *einfo){ Method *new_methods = 0; int retval = 0; /* if( !CLASS_IS_ABSTRACT(cl) ) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "(class: %s, method: %s signature: %s) " "Abstract method in non-abstract class", cl->name->data, imeth->name->data, imeth->parsed_sig->signature->data); } else */ if( (new_methods = gc_realloc(CLASS_METHODS(cl), sizeof(Method) * (CLASS_NMETHODS(cl) + 1), GC_ALLOC_METHOD)) ) { int index; index = CLASS_NMETHODS(cl); CLASS_NMETHODS(cl) = index + 1; CLASS_METHODS(cl) = new_methods; utf8ConstAddRef(imeth->name); utf8ConstAddRef(imeth->parsed_sig->signature); new_methods[index] = *imeth; new_methods[index].ndeclared_exceptions = -1; new_methods[index].declared_exceptions_u.remote_exceptions = imeth; new_methods[index].class = cl; retval = 1; } else { gc_free(new_methods); postOutOfMemory(einfo); } return( retval );}static intexpandInterfaces(Hjava_lang_Class *root_class, Hjava_lang_Class *class, errorInfo *einfo){ int i, j, k, success = 1; /* * Check to make sure all the interface methods are implemented, * otherwise, we'll need to add a slot. */ for( i = 0; (i < class->interface_len) && success; i++ ) { Hjava_lang_Class *iface; iface = class->interfaces[i]; if( !expandInterfaces(root_class, iface, einfo) ) { success = 0; break; } for( j = 0; (j < CLASS_NMETHODS(iface)) && success; j++ ) { Hjava_lang_Class *cl; int foundit = 0; Method *imeth; imeth = &CLASS_METHODS(iface)[j]; /* Igore statics */ if( imeth->accflags & ACC_STATIC ) continue; /* Search for the corresponding slot. */ for( cl = root_class; cl && !foundit; cl = cl->superclass ) { for( k = 0; k < CLASS_NMETHODS(cl); k++ ) { Method *cmeth; cmeth = &CLASS_METHODS(cl)[k]; if( (cmeth->name == imeth->name) && (cmeth->parsed_sig->signature == imeth->parsed_sig->signature) ) { foundit = 1; break; } } } if( !foundit ) { /* No impl, add a slot */ success = expandMethods(root_class, imeth, einfo); } } } return( success );}static boolresolveInterfaces(Hjava_lang_Class *class, errorInfo *einfo){ int iLockRoot; int i, j, k; int totalilen; Hjava_lang_Class** newifaces; Hjava_lang_Class* nclass; bool success = true; /* optimistic */ /* Load all the implemented interfaces. */ j = class->interface_len; nclass = class->superclass; if (nclass != 0 && nclass != ObjectClass) { /* If class is an interface, its superclass must * be java.lang.Object or the class file is broken. */ if (CLASS_IS_INTERFACE(class)) { postException(einfo, JAVA_LANG(VerifyError)); success = false; goto done; } j += class->superclass->total_interface_len; } for (i = 0; i < class->interface_len; i++) { uintp iface = (uintp)class->interfaces[i]; unlockClass(class);#if defined(HAVE_GCJ_SUPPORT) if (CLASS_GCJ(class)) { nclass = gcjGetClass((void*)iface, einfo); } else { nclass = getClass(iface, class, einfo); }#else nclass = getClass(iface, class, einfo);#endif /* HAVE_GCJ_SUPPORT */ class->interfaces[i] = nclass; lockClass(class); if (class->interfaces[i] == 0) { success = false; goto done; } if (!(class->interfaces[i]->accflags & ACC_INTERFACE)) { postExceptionMessage( einfo, JAVA_LANG(IncompatibleClassChangeError), "Class, %s, used as interface by %s", class->interfaces[i]->name->data, class->name->data); success = false; goto done; } if (instanceof(class, class->interfaces[i])) { postExceptionMessage( einfo, JAVA_LANG(ClassCircularityError), "%s", class->name->data); success = false; goto done; } j += class->interfaces[i]->total_interface_len; } totalilen = j; /* We build a list of *all* interfaces this class can use */ if (class->interface_len != j) { newifaces = (Hjava_lang_Class**)gc_malloc(sizeof(Hjava_lang_Class**) * j, GC_ALLOC_INTERFACE); if (newifaces == 0) { postOutOfMemory(einfo); success = false; goto done; } for (i = 0; i < class->interface_len; i++) { newifaces[i] = class->interfaces[i]; } nclass = class->superclass; if (nclass != 0 && nclass != ObjectClass) { for (j = 0; j < nclass->total_interface_len; j++, i++) { newifaces[i] = nclass->interfaces[j]; } } for (k = 0; k < class->interface_len; k++) { nclass = class->interfaces[k]; for (j = 0; j < nclass->total_interface_len; j++, i++) { newifaces[i] = nclass->interfaces[j]; } } /* free old list of interfaces */ if (class->interfaces != 0) { KFREE(class->interfaces); } class->interfaces = newifaces; } /* don't set total_interface_len before interfaces to avoid * having walkClass attempting to walk interfaces */ class->total_interface_len = totalilen; if( !CLASS_IS_INTERFACE(class) ) { success = expandInterfaces(class, class, einfo); }done: return (success);}/** * Check if a class name is in a set of packages. * * XXX Move somewhere else... * * @param plist The null terminated list of packages to check against. * @param name The class name to check. * @return True if the class name is in one of the packages, false otherwise. */static intinPackageSet(char **plist, Utf8Const *name){ int name_len, lpc, retval = 0; name_len = strlen(name->data); for( lpc = 0; plist[lpc] && !retval; lpc++ ) { int len; len = strlen(plist[lpc]); if( (name_len > len) && strncmp(name->data, plist[lpc], len) == 0 ) { retval = 1; } } return( retval );}/** * The set of restricted packages that a user defined class loader can't add * classes to. */static char *restrictedPackages[] = { "java/", "kaffe/", NULL};static intinternalSetupClass(Hjava_lang_Class* cl, Utf8Const* name, int flags, int this_index, int su, Hjava_lang_ClassLoader* loader, struct _errorInfo *einfo){ if( (loader != NULL) && inPackageSet(restrictedPackages, name) ) { /* * Can't allow users to add classes to the bootstrap * packages. */ postExceptionMessage(einfo, JAVA_LANG(SecurityException), "Prohibited package: %s", name->data); return 0; } if( cl->name == NULL ) { utf8ConstAssign(cl->name, name); } else if( !utf8ConstEqual(cl->name, name) ) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "%s (wrong name: %s)", name->data, cl->name->data); return 0; } cl->packageLength = findPackageLength(name->data); CLASS_METHODS(cl) = NULL; CLASS_NMETHODS(cl) = 0; assert(cl->superclass == 0); cl->superclass = (Hjava_lang_Class*)(uintp)su; cl->msize = 0; CLASS_FIELDS(cl) = 0; CLASS_FSIZE(cl) = 0; cl->accflags = flags; cl->dtable = 0; cl->interfaces = 0; cl->interface_len = 0; assert(cl->state < CSTATE_LOADED); cl->state = CSTATE_LOADED; cl->loader = loader; cl->this_index = this_index; cl->inner_classes = 0; cl->nr_inner_classes = 0; cl->this_inner_index = -1; return 1;}Hjava_lang_Class*setupClass(Hjava_lang_Class* cl, constIndex c, constIndex s, u2 flags, Hjava_lang_ClassLoader* loader, errorInfo* einfo){ constants* pool; pool = CLASS_CONSTANTS(cl); /* Find the name of the class */ if (pool->tags[c] != CONSTANT_Class) { postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "this class constant pool index is bogus"); return false; } if (!internalSetupClass(cl, WORD2UTF(pool->data[c]), flags, c, s, loader, einfo)) return 0; return (cl);}/* * add source file name to be printed in exception backtraces */booladdSourceFile(Hjava_lang_Class* c, int idx, errorInfo *einfo){ constants* pool; const char* sourcefile; const char* basename; bool success = true; pool = CLASS_CONSTANTS (c); sourcefile = WORD2UTF (pool->data[idx])->data; basename = strrchr(sourcefile, '/'); if (basename == 0) { basename = sourcefile; } else { basename++; } c->sourcefile = gc_malloc(strlen(basename) + 1, GC_ALLOC_CLASSMISC); if (c->sourcefile != 0) { strcpy(c->sourcefile, basename); } else { success = false; postOutOfMemory(einfo); } /* we should be able to drop this utf8 here */ utf8ConstRelease(WORD2UTF (pool->data[idx])); pool->data[idx] = 0; return (success);}/* * Read in InnerClasses declares for a class */booladdInnerClasses(Hjava_lang_Class* c, uint32 len, classFile* fp, errorInfo *einfo){ int i; u2 nr; innerClass *ic; if (! checkBufSize(fp, 2, CLASS_CNAME(c), einfo)) return false; readu2(&nr, fp); if (nr == 0) { return true; } if (! checkBufSize(fp, nr*(2*4), CLASS_CNAME(c), einfo)) return false; ic = gc_malloc(sizeof(innerClass) * nr, GC_ALLOC_CLASSMISC); if (!ic) { postOutOfMemory(einfo); return false; } c->nr_inner_classes = nr; c->inner_classes = ic; for (i = 0; i < nr; i++, ic++) { u2 dummy; readu2(&ic->inner_class, fp); readu2(&ic->outer_class, fp); readu2(&dummy, fp); readu2(&ic->inner_class_accflags, fp); if (c->this_index && ic->inner_class == c->this_index) { c->accflags = (c->accflags & ~ACC_MASK) | (ic->inner_class_accflags & ACC_MASK); c->this_inner_index = i; } } return true;}intstartMethods(Hjava_lang_Class* this, u2 methct, errorInfo *einfo){ if (methct == 0) { this->methods = NULL; } else { this->methods = gc_malloc(sizeof(Method)*(methct), GC_ALLOC_METHOD); if (this->methods == NULL) { postOutOfMemory(einfo); return false; } } GC_WRITE(this, this->methods); this->nmethods = 0; /* updated in addMethod */ return true;}Method*addMethod(Hjava_lang_Class* c, u2 access_flags, u2 name_index, u2 signature_index, errorInfo *einfo){ constIndex nc; constIndex sc; Method* mt; constants* pool; Utf8Const* name; Utf8Const* signature;#ifdef KAFFE_VMDEBUG int ni;#endif pool = CLASS_CONSTANTS (c); nc = name_index; if (pool->tags[nc] != CONSTANT_Utf8) { /* XXX fill in einfo! */DBG(RESERROR, dprintf("addMethod: no method name.\n"); ) postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "No method name"); return (0); } sc = signature_index; if (pool->tags[sc] != CONSTANT_Utf8) { /* XXX fill in einfo! */DBG(RESERROR, dprintf("addMethod: no signature name.\n"); )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?