classmethod.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 2,775 行 · 第 1/5 页
C
2,775 行
postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "No signature for method: %s", WORD2UTF (pool->data[nc])->data); return (0); } name = WORD2UTF (pool->data[nc]); signature = WORD2UTF (pool->data[sc]);#ifdef KAFFE_VMDEBUG /* Search down class for method name - don't allow duplicates */ for (ni = CLASS_NMETHODS(c), mt = CLASS_METHODS(c); --ni >= 0; ) { assert(! utf8ConstEqual (name, mt->name) || ! utf8ConstEqual (signature, METHOD_SIG(mt))); }#endifDBG(CLASSFILE, dprintf("Adding method %s:%s%s (%x)\n", c->name->data, name->data, signature->data, access_flags); ) mt = &CLASS_METHODS(c)[CLASS_NMETHODS(c)]; utf8ConstAssign(mt->name, name); METHOD_PSIG(mt) = parseSignature(signature, einfo); if (METHOD_PSIG(mt) == NULL) { return NULL; } mt->class = c; /* Warning: ACC_CONSTRUCTION match ACC_STRICT */ mt->accflags = access_flags & ACC_MASK; mt->c.bcode.code = 0; mt->stacksz = 0; mt->localsz = 0; mt->exception_table = 0; mt->idx = -1; /* Mark constructors as such */ if (utf8ConstEqual (name, constructor_name)) { mt->accflags |= ACC_CONSTRUCTOR; } CLASS_NMETHODS(c)++; return (mt);}Field*addField(Hjava_lang_Class* c, u2 access_flags, u2 name_index, u2 signature_index, errorInfo* einfo){ constIndex nc; constIndex sc; Field* ft; constants* pool; int index; const char* sig; pool = CLASS_CONSTANTS (c); nc = name_index; if (pool->tags[nc] != CONSTANT_Utf8) {DBG(RESERROR, dprintf("addField: no field name.\n"); ) postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "No field name"); return (0); } --CLASS_FSIZE(c); /* holds field count initially */ if (access_flags & ACC_STATIC) { index = CLASS_NSFIELDS(c); } else { index = CLASS_FSIZE(c) + CLASS_NSFIELDS(c); } ft = &CLASS_FIELDS(c)[index]; ft->clazz = c; DBG(CLASSFILE, dprintf("Adding field %s:%s\n", CLASS_CNAME(c), CLASS_CONST_UTF8(c, nc)->data); ) sc = signature_index; if (pool->tags[sc] != CONSTANT_Utf8) {DBG(RESERROR, dprintf("addField: no signature name.\n"); ) postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "No signature name for field: %s", CLASS_CONST_UTF8(c, nc)->data); CLASS_NFIELDS(c)++; return (0); } utf8ConstAssign(ft->name, WORD2UTF(pool->data[nc])); utf8ConstAssign(ft->signature, CLASS_CONST_UTF8(c, sc)); ft->accflags = access_flags; sig = ft->signature->data; if (sig[0] == 'L' || sig[0] == '[') { /* This `type' field is used to hold a utf8Const describing * the type of the field. This utf8Const will be replaced * with a pointer to an actual class type in resolveFieldType * Between now and then, we add a reference to it. */ ft->accflags |= FIELD_UNRESOLVED_FLAG; FIELD_SIZE(ft) = PTR_TYPE_SIZE; } else { /* NB: since this class is primitive, getClassFromSignature * will not fail. Hence it's okay to pass errorInfo as NULL */ FIELD_TYPE(ft) = getClassFromSignature(sig, 0, NULL); FIELD_SIZE(ft) = TYPE_PRIM_SIZE(FIELD_TYPE(ft)); } CLASS_NFIELDS(c)++; if (access_flags & ACC_STATIC) { CLASS_NSFIELDS(c)++; } return (ft);}voidsetFieldValue(Hjava_lang_Class* unused, Field* ft, u2 idx){ /* Set value index */ FIELD_CONSTIDX(ft) = idx; ft->accflags |= FIELD_CONSTANT_VALUE;}intstartFields(Hjava_lang_Class* this, u2 fieldct, errorInfo *einfo){ CLASS_NFIELDS(this) = 0; /* updated in addField() */ CLASS_FSIZE(this) = fieldct; if (fieldct == 0) { CLASS_FIELDS(this) = (Field*)0; } else { CLASS_FIELDS(this) = (Field*) gc_malloc(sizeof(Field) * fieldct, GC_ALLOC_FIELD); if (!CLASS_FIELDS(this)) { postOutOfMemory(einfo); return false; } } GC_WRITE(this, CLASS_FIELDS(this)); /* XXX */ return true;}voidfinishFields(Hjava_lang_Class *cl){ Field tmp; Field* fld; int n; /* Reverse the instance fields, so they are in "proper" order. */ fld = CLASS_IFIELDS(cl); n = CLASS_NIFIELDS(cl); while (n > 1) { tmp = fld[0]; fld[0] = fld[n-1]; fld[n-1] = tmp; fld++; n -= 2; }}voidaddMethodCode(Method* m, Code* c){ assert(m != 0); assert(c != 0); assert(c->code != 0); assert(c->code_length != 0); m->c.bcode.code = c->code; m->c.bcode.codelen = c->code_length; m->stacksz = c->max_stack; m->localsz = c->max_locals; m->exception_table = c->exception_table;}voidaddInterfaces(Hjava_lang_Class* c, u2 inr, Hjava_lang_Class** inf){ assert(c); assert(inr > 0); c->interfaces = inf; c->interface_len = inr; GC_WRITE(c, c->interfaces); /* XXX */}staticHjava_lang_Class *userLoadClass(classEntry *ce, Hjava_lang_ClassLoader *loader, errorInfo *einfo){ Hjava_lang_Class *retval = NULL; JNIEnv *env = THREAD_JNIENV(); Hjava_lang_String *jname; jthrowable excpending; jmethodID meth; /* * If an exception is already pending, for instance because we're * resolving one that has occurred, save it and clear it for the * upcall. */ excpending = (*env)->ExceptionOccurred(env); (*env)->ExceptionClear(env); if( (jname = utf8Const2JavaReplace(ce->name, '/', '.')) && /* * We use JNI here so that all exceptions are caught and we'll * always return. */ (meth = (*env)->GetMethodID( env, (*env)->GetObjectClass(env, loader), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;")) ) { jthrowable excobj; retval = (Hjava_lang_Class*) (*env)->CallObjectMethod(env, loader, meth, jname); /* * Check whether an exception occurred. If one was pending, * the new exception will override this one. */ excobj = (*env)->ExceptionOccurred(env); (*env)->ExceptionClear(env); if( excobj != 0 ) { /* There was an exception. */ einfo->type = KERR_RETHROW; einfo->throwable = excobj; if( soft_instanceof(javaLangClassNotFoundException, (Hjava_lang_Object *) einfo->throwable) ) { /* Set this for the verifier. */ einfo->type |= KERR_NO_CLASS_FOUND; } } else if( retval == NULL ) { /* No class returned. */ postExceptionMessage(einfo, JAVA_LANG(ClassNotFoundException), "%s", ce->name->data); /* Set this for the verifier. */ einfo->type |= KERR_NO_CLASS_FOUND; } else if( !utf8ConstEqual(retval->name, ce->name) ) { /* * Its a valid class, but the name differs from the one * that was requested. */ postExceptionMessage( einfo, JAVA_LANG(ClassNotFoundException), "Bad class name (expect: %s, get: %s)", ce->name->data, retval->name->data); /* Set this for the verifier. */ einfo->type |= KERR_NO_CLASS_FOUND; retval = NULL; } else { retval = classMappingLoaded(ce, retval); } } else { postOutOfMemory(einfo); } /* rethrow pending exception */ if( excpending != NULL ) { (*env)->Throw(env, excpending); } return( retval );}Hjava_lang_Class *loadClass(Utf8Const *name, Hjava_lang_ClassLoader *loader, errorInfo *einfo){ Hjava_lang_Class *retval = NULL; classEntry *ce; if( (ce = lookupClassEntry(name, loader, einfo)) ) { if( classMappingSearch(ce, &retval, einfo) ) { if( retval == NULL ) { /* Loading is this thread's responsibility. */ if( loader ) {DBG(VMCLASSLOADER, /* Announce when VM calls class loaders.. */ dprintf("Calling user-defined class loader %s - loadClass(%s)\n", CLASS_CNAME(OBJECT_CLASS(&loader->base)), ce->name->data);) /* Use a user defined loader. */ retval = userLoadClass(ce, loader, einfo); } else {DBG(VMCLASSLOADER, /* Announce when VM calls class loaders.. */ dprintf("Calling internal class loader for %s\n", ce->name->data);) /* Use the primordial loader. */ retval = findClass(ce, einfo); } } else { /* Class is already loaded. */ } if( !retval ) { /* No joy, update state. */ setClassMappingState(ce, NMS_EMPTY); } else if( processClass(retval, CSTATE_LINKED, einfo) == false ) { retval = NULL; } } else { /* Class circularity, or some other error. */ } } else { /* No memory? */ } return( retval );}Hjava_lang_Class*loadArray(Utf8Const* name, Hjava_lang_ClassLoader* loader, errorInfo *einfo){ Hjava_lang_Class *clazz; clazz = getClassFromSignature(&name->data[1], loader, einfo); if (clazz != 0) { if( (clazz = lookupArray(clazz, einfo)) ) { return( clazz ); } else { /* XXX Is it always class not found? */ discardErrorInfo(einfo); postExceptionMessage(einfo, JAVA_LANG(ClassNotFoundException), "%s", name->data); } } else { discardErrorInfo(einfo); postExceptionMessage(einfo, JAVA_LANG(ClassNotFoundException), "%s", name->data); } return (0);}/* * Load a class to whose Class object we refer globally. * This is used only for essential classes, so let's bail if this fails. */voidloadStaticClass(Hjava_lang_Class** class, const char* name){ Hjava_lang_Class *clazz; errorInfo info; Utf8Const *utf8; classEntry* centry; int iLockRoot; utf8 = utf8ConstNew(name, -1); if (!utf8) goto bad; centry = lookupClassEntry(utf8, 0, &info); if (!centry) goto bad; utf8ConstRelease(utf8); lockMutex(centry); if (centry->data.cl == 0) { centry->state = NMS_LOADING;DBG(VMCLASSLOADER, /* Announce when VM calls class loaders.. */ dprintf("Calling internal class loader for startup class %s\n", name);) clazz = findClass(centry, &info); if (clazz == 0) { goto bad; } /* we won't ever want to lose these classes */ if (!gc_add_ref(clazz)) { goto bad; } (*class) = centry->data.cl = clazz; } unlockMutex(centry); if (!(*class)) (*class) = centry->data.cl; if (processClass(centry->data.cl, CSTATE_LINKED, &info) == true) { assert(centry->state == NMS_DONE); return; }bad: dprintf("Couldn't find or load essential class `%s' %s %s\n", name, info.classname, (char*)info.mess); ABORT();}/* * Look a class up by name. */Hjava_lang_Class*lookupClass(const char* name, Hjava_lang_ClassLoader* loader, errorInfo *einfo){ Hjava_lang_Class* class; Utf8Const *utf8; utf8 = utf8ConstNew(name, -1); if (!utf8) { postOutOfMemory(einfo); return 0; } class = loadClass(utf8, loader, einfo); utf8ConstRelease(utf8); if (class != 0) { if (processClass(class, CSTATE_COMPLETE, einfo) == true) { return (class); } } return (0);}/* * Return FIELD_TYPE(FLD), but if !FIELD_RESOLVED, resolve the field first. */Hjava_lang_Class*resolveFieldType(Field *fld, Hjava_lang_Class* this, errorInfo *einfo){ Hjava_lang_Class* clas; const char* name; int iLockRoot; /* Avoid locking if we can */ if (FIELD_RESOLVED(fld)) { return (FIELD_TYPE(fld)); } /* We must lock the class while we retrieve the field name and * while we resolve it - or we may release the utf8's field type twice */ lockClass(this); if (FIELD_RESOLVED(fld)) { unlockClass(this); return (FIELD_TYPE(fld)); } name = fld->signature->data; if( (clas = getClassFromSignature(name, this->loader, einfo)) ) { FIELD_TYPE(fld) = clas; fld->accflags &= ~FIELD_UNRESOLVED_FLAG; } unlockClass(this); return (clas);}staticboolresolveObjectFields(Hjava_lang_Class* class, errorInfo *einfo){ int fsize; int align; Field* fld; int nbits, n; int offset; int maxalign; int oldoffset; int *map; /* Find start of new fields in this object. If start is zero, we must * allow for the object headers. */ offset = CLASS_FSIZE(class); oldoffset = offset; /* remember initial offset */ if (offset == 0) { offset = sizeof(Hjava_lang_Object); } /* Find the largest alignment in this class */ maxalign = 1; fld = CLASS_IFIELDS(class); n = CLASS_NIFIELDS(class); for (; --n >= 0; fld++) { fsize = FIELD_SIZE(fld); /* Work out alignment for this size entity */ fsize = ALIGNMENT_OF_SIZE(fsize); /* If field is bigger than biggest alignment, change * biggest alignment */ if (fsize > maxalign) { maxalign = fsize; } }#if 0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?