classmethod.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 2,775 行 · 第 1/5 页
C
2,775 行
/* not found */ cmeth = 0; found:; /* constructors and static methods cannot implement * interface methods */ if (cmeth && (METHOD_IS_STATIC(cmeth) || METHOD_IS_CONSTRUCTOR(cmeth))) { cmeth = 0; } /* cmeth == 0 if * This class does not implement the interface at all. * Or if the class attempts to implement an interface * method with a static method or constructor. */ if (cmeth == 0) { class->itable2dtable[j] = (void *)-1; } else { if (buildTrampoline(cmeth, class->itable2dtable + j, einfo) == 0) { return (false); } } j++; } } return (true);}/* * Compute the interface implementation index for this class. * The impl_index is an index for each class that is used to index the * implementor table of the interface when dispatching an interface * method. See soft_lookupinterfacemethod in soft.c * It points directly at the first itable2dtable index for the section * that describes the interface (which is what's now redundantly stored * in if2itable[x].) * * This allows interface lookup in constant time. */static boolcomputeInterfaceImplementationIndex(Hjava_lang_Class* clazz, errorInfo* einfo){ int i, j, k; int found_i; bool rc = false; Hjava_lang_Class** ifcs; int iLockRoot; /* find an impl_index for this class * Note that we only find a suitable impl_index with regard to the * interfaces this class implements, not a globally unique one. * * In other words, two classes implementing disjoint sets of * interfaces may end up with the same impl_index. For this reason, * the impl_index at this point cannot be used to implement the * equivalent of instanceof <interface> * * We assume that a verifier design is possible that will ensure * that a run-time object indeed implements an interface at the * time when soft_lookupinterfacemethod is invoked. We do not have * such a verifier at this point. */ if (clazz->total_interface_len == 0) { return (true); } /* We are manipulating the implementor tables of all implemented * interfaces. We must lock them. To avoid deadlock, lets lock * them in ascending order. */ ifcs = KMALLOC(clazz->total_interface_len * sizeof(Hjava_lang_Class*)); memcpy(ifcs, clazz->interfaces, clazz->total_interface_len * sizeof(Hjava_lang_Class*)); /* this is bubble-sort */ do { k = 0; for (j = 0; j < clazz->total_interface_len - 1; j++) { Hjava_lang_Class* iface_j = ifcs[j]; Hjava_lang_Class* iface_j1 = ifcs[j+1]; if (iface_j - iface_j1 > 0) { k = 1; ifcs[j] = iface_j1; ifcs[j+1] = iface_j; } } } while (k); for (j = 0; j < clazz->total_interface_len; j++) { lockClass(ifcs[j]); } i = 0; do { found_i = 1; for (j = 0; j < clazz->total_interface_len; j++) { Hjava_lang_Class* iface = clazz->interfaces[j]; int len = 0; if (iface->implementors != 0) { /* This is how many entries follow, so the * array has a[0] + 1 elements */ len = iface->implementors[0]; } if (i >= len || iface->implementors[i+1] == -1) { continue; /* this one would work */ } else { found_i = 0; break; } } i++; } while (!found_i); /* 'i' is a suitable index --- note we incremented i before leaving * the loop above. */ clazz->impl_index = i; /* Now patch all interfaces to point back to their itable2dtable * regions in the dispatch table of this implementing class. */ for (j = 0; j < clazz->total_interface_len; j++) { Hjava_lang_Class* iface = clazz->interfaces[j]; short len; /* make sure the implementor table is big enough */ if (iface->implementors == NULL || i > iface->implementors[0]) { short firstnewentry; if (iface->implementors == NULL) { len = (i + 1) + 4; /* 4 is slack only */ iface->implementors = gc_malloc(len * sizeof(short), GC_ALLOC_CLASSMISC); } else { /* double in size */ len = iface->implementors[0] * 2; if (len <= i) { len = i + 4; } iface->implementors = gc_realloc( iface->implementors, len * sizeof(short), GC_ALLOC_CLASSMISC); } if (iface->implementors == 0) { postOutOfMemory(einfo); goto done; } /* NB: we assume KMALLOC/KREALLOC zero memory out */ firstnewentry = iface->implementors[0] + 1; iface->implementors[0] = len - 1; /* mark new entries as unused */ for (k = firstnewentry; k < len; k++) { iface->implementors[k] = -1; } } assert(i < iface->implementors[0] + 1); iface->implementors[i] = clazz->if2itable[j]; } rc = true;done: for (j = clazz->total_interface_len - 1; j >= 0; j--) { unlockClass(ifcs[j]); } KFREE(ifcs); return (rc);}/* Check for undefined abstract methods if class is not abstract. * See "Java Language Specification" (1996) section 12.3.2. * * Returns true if the class is abstract or if no abstract methods were * found, false otherwise. */staticboolcheckForAbstractMethods(Hjava_lang_Class* class, errorInfo *einfo){ int i; void **mtab = class->dtable->method; if ((class->accflags & ACC_ABSTRACT) == 0) { for (i = 0; i < class->msize; i++) { if (mtab[i] == NULL) { postException(einfo, JAVA_LANG(AbstractMethodError)); return (false); } } } return (true);}/* * This functions simply assign indices to the virtual methods in an * interface. * * In addition, if the interface has a <clinit> method, it builds a * trampoline for it. */staticboolprepareInterface(Hjava_lang_Class* class, errorInfo *einfo){ Method* meth; int i; meth = CLASS_METHODS(class); class->msize = 0; /* enumerate indices and store them in meth->idx */ for (i = 0; i < CLASS_NMETHODS(class); i++, meth++) { if (meth->accflags & ACC_STATIC) { meth->idx = -1;#if defined(TRANSLATOR) /* Handle <clinit> */ if (utf8ConstEqual(meth->name, init_name)) { void **where; where = (void**)PMETHOD_NATIVECODE(meth); if (buildTrampoline(meth, where, einfo) == 0) { return (false); } }#endif } else { meth->idx = class->msize++; } } return (true);}/* * convert a CONSTANT_String entry in the constant poool * from utf8 to java.lang.String */Hjava_lang_String*resolveString(Hjava_lang_Class* clazz, int idx, errorInfo *info){ Utf8Const* utf8; Hjava_lang_String* str = 0; constants* pool; int iLockRoot; pool = CLASS_CONSTANTS(clazz); lockClass(clazz); switch (pool->tags[idx]) { case CONSTANT_String: utf8 = WORD2UTF(pool->data[idx]); str = utf8Const2Java(utf8); if (!str) { postOutOfMemory(info); break; } pool->data[idx] = (ConstSlot)str; pool->tags[idx] = CONSTANT_ResolvedString; utf8ConstRelease(utf8); break; case CONSTANT_ResolvedString: /* somebody else resolved it */ str = (Hjava_lang_String*)pool->data[idx]; break; default: assert(!!!"Neither String nor ResolvedString?"); } unlockClass(clazz); return (str);}#undef EAGER_LOADING/* * Initialise the constants. * First we make sure all the constant strings are converted to java strings. * * This code removed: * There seems to be no need to be so eager in loading * referenced classes or even resolving strings. */staticboolresolveConstants(Hjava_lang_Class* class, errorInfo *einfo){ bool success = true;#ifdef EAGER_LOADING iLock* lock; int idx; constants* pool; Utf8Const* utf8; lockClass(class); /* Scan constant pool and convert any constant strings into true * java strings. */ pool = CLASS_CONSTANTS (class); for (idx = 0; idx < pool->size; idx++) { switch (pool->tags[idx]) { case CONSTANT_String: utf8 = WORD2UTF(pool->data[idx]); /* XXX: unchecked malloc */ pool->data[idx] = (ConstSlot)utf8Const2Java(utf8); pool->tags[idx] = CONSTANT_ResolvedString; utf8ConstRelease(utf8); break; case CONSTANT_Class: if (getClass(idx, class, einfo) == 0) { success = false; goto done; } break; } }done: unlockClass(this);#endif /* EAGER_LOADING */ return (success);}/* * Lookup a named field. Do not search super classes. Do not resolve the field. */static Field*lookupClassFieldLocal(Hjava_lang_Class* clp, Utf8Const* name, bool isStatic){ Field* fptr; int n; /* Search down class for field name */ if (isStatic) { fptr = CLASS_SFIELDS(clp); n = CLASS_NSFIELDS(clp); } else { fptr = CLASS_IFIELDS(clp); n = CLASS_NIFIELDS(clp); } while (--n >= 0) { if (utf8ConstEqual (name, fptr->name)) { return (fptr); } fptr++; } return (0);}/* * Lookup a named field. Search superclasses and resolve the field. */Field*lookupClassField(Hjava_lang_Class* clp, Utf8Const* name, bool isStatic, errorInfo *einfo){ Field *fptr; Hjava_lang_Class *c; for (c = clp; c; c = c->superclass) { fptr = lookupClassFieldLocal(c, name, isStatic); if (fptr) { /* Resolve field if necessary */ if (resolveFieldType(fptr, c, einfo) == 0) { return (NULL); } return (fptr); } } if (isStatic) { int i = clp->total_interface_len; Hjava_lang_Class **cp = &clp->interfaces[0]; while (--i >= 0) { fptr = lookupClassFieldLocal (*cp, name, true); if (fptr) { if (resolveFieldType(fptr, *cp, einfo) == 0) { return (NULL); } return (fptr); } cp++; } }DBG(RESERROR, dprintf("lookupClassField for %s failed %s:%s\n", isStatic?"static":"non-static",clp->name->data, name->data); ) postExceptionMessage(einfo, JAVA_LANG(NoSuchFieldError), "%s", name->data); return (0);}/* * Determine the number of arguments and return values from the * method signature. */voidcountInsAndOuts(const char* str, short* ins, short* outs, char* outtype){ *ins = sizeofSig(&str, false); *outtype = str[0]; *outs = sizeofSig(&str, false);}/* * Calculate size (in words) of a signature item. */intsizeofSigChar(char ch, bool want_wide_refs){ switch (ch) { case 'V': return 0; case 'I': case 'Z': case 'S': case 'B': case 'C': case 'F': return 1; break; case 'D': case 'J': return 2; break; case '[': case 'L': return want_wide_refs ? sizeof(void*) / sizeof(int32) : 1; } return -1;}/* * Calculate size (in words) of a signature item and move *strp so * that it points to the next element of the signature */intsizeofSigItem(const char** strp, bool want_wide_refs){ int count; const char* str; for (str = *strp; ; str++) { count = sizeofSigChar(*str, want_wide_refs); if (count == -1) { switch (*str) { case '(': continue; case 0: case ')': break; default: count = -1; /* avoid compiler warning */ ABORT(); } } else { while (*str == '[') ++str; if (*str == 'L') { while (*str != ';') { str++; } } } *strp = str + 1; return (count); }}/* * Calculate size of data item based on signature and move *strp so * that it points to the next element of the signature. */intsizeofSig(const char** strp, bool want_wide_refs){ int count; int c; count = 0; for (;;) { c = sizeofSigItem(strp, want_wide_refs); if (c == -1) { return (count); } count += c; }}/* * Calculate size (in words) of a Class. */intsizeofSigClass(Hjava_lang_Class* clazz, bool want_wide_refs){ return sizeofSigChar(CLASS_IS_PRIMITIVE(clazz) ? CLASS_PRIM_SIG(clazz) : 'L', want_wide_refs);}/* * Calculate size (in words) of the signature of a Method. */intsizeofSigMethod(Method *meth, bool want_wide_refs){ int i = 0, args = METHOD_NARGS(meth), size = 0; while (i < args) { size += sizeofSigChar(*METHOD_ARG_TYPE(meth, i), want_wide_refs); ++i; } return (size);}/* * Count the number of arguments in a signature. */intcountArgsInSignature(const char *signature){ int nargs = 0; while (sizeofSigItem(&signature, false) != -1) { ++nargs; } return (nargs);}/* * Parse a method signature and return an array of pointers to classes. */parsed_signature_t*parseSignature(Utf8Const *signature, errorInfo *einfo
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?