📄 class.c
字号:
{ Method* mth = CLASS_METHODS(clas); int i; int count = 0; for (i = CLASS_NMETHODS(clas)-1 ; i >= 0; i--) { if (((mth[i].accflags & ACC_PUBLIC) || declared) && !(mth[i].accflags & ACC_CONSTRUCTOR) && !isOverridden(base, clas, mth + i) && !utf8ConstEqual(init_name, mth[i].name)) { count++; } } return count;}/* * create reflect.Method objects for all methods in a class that are * not constructors. If declared is not set, include only public methods. */static voidaddMethods(Hjava_lang_Class* base, Hjava_lang_Class* clas, jint declared, Hjava_lang_reflect_Method*** ptr){ Method* mth = CLASS_METHODS(clas); int i; for (i = CLASS_NMETHODS(clas)-1; i >= 0; i--) { if (((mth[i].accflags & ACC_PUBLIC) || declared) && !(mth[i].accflags & ACC_CONSTRUCTOR) && !isOverridden(base, clas, mth + i) && !utf8ConstEqual(init_name, mth[i].name)) { **ptr = makeMethod(clas, i); (*ptr)++; } }}/* * Reflect all methods implemented by an interface or one of its * superinterfaces. * * Note that we do not reach the "superinterface" via the superclass pointer. * See the VM Spec, which says: * * "The implements clause in a [interface] class declaration lists the * names of interfaces that are direct superinterfaces of the [interface] * class being declared." * * Hence we must look at the interfaces list for superinterfaces. */staticHArrayOfObject*getInterfaceMethods0(struct Hjava_lang_Class* this, jint declared){ int count; Hjava_lang_reflect_Method** ptr; HArrayOfObject* array; int i; count = 0; count += countMethods(0, this, declared); if (!declared) { for (i = 0; i < this->total_interface_len; i++) { count += countMethods(0, this->interfaces[i], declared); } } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/reflect/Method;", 0); ptr = (Hjava_lang_reflect_Method**)&unhand_array(array)->body[0]; addMethods(0, this, declared, &ptr); if (!declared) { for (i = 0; i < this->total_interface_len; i++) { addMethods(0, this->interfaces[i], declared, &ptr); } } return (array);}HArrayOfObject*java_lang_Class_getMethods0(struct Hjava_lang_Class* this, jboolean declared){ int count; Hjava_lang_Class* clas; Hjava_lang_reflect_Method** ptr; HArrayOfObject* array; /* * Note: the spec wants us to include the methods of all superclasses * and all superinterfaces. * * Superinterfaces cannot be reached through the superclass * pointer. We handle them in a separate function. */ if (CLASS_IS_INTERFACE(this)) return (getInterfaceMethods0(this, declared)); count = 0; for (clas = this; clas != NULL; clas = clas->superclass) { count += countMethods(this, clas, declared); if (declared) { break; } } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/reflect/Method;", 0); ptr = (Hjava_lang_reflect_Method**)&unhand_array(array)->body[0]; for (clas = this; clas != NULL; clas = clas->superclass) { addMethods(this, clas, declared, &ptr); if (declared) { break; } } return (array);}HArrayOfObject*java_lang_Class_getConstructors0(struct Hjava_lang_Class* this, jboolean declared){ int count; Hjava_lang_Class* clas; Method* mth; Hjava_lang_reflect_Constructor** ptr; HArrayOfObject* array; int i; count = 0; clas = this; mth = CLASS_METHODS(clas); for (i = CLASS_NMETHODS(clas)-1; i >= 0; i--) { if (((mth[i].accflags & ACC_PUBLIC) || declared) && (mth[i].accflags & ACC_CONSTRUCTOR)) { count++; } } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/reflect/Constructor;", 0); ptr = (Hjava_lang_reflect_Constructor**)&unhand_array(array)->body[0]; clas = this; mth = CLASS_METHODS(clas); for (i = CLASS_NMETHODS(clas)-1; i >= 0; i--) { if (((mth[i].accflags & ACC_PUBLIC) || declared) && (mth[i].accflags & ACC_CONSTRUCTOR)) { *ptr = makeConstructor(clas, i); ptr++; } } return (array);}/* * Count all public fields of a class, including inherited fields and * fields from implemented interfaces */static intcountPublicFields(Hjava_lang_Class* clazz){ Hjava_lang_Class* clas; int i, count; count = 0; for (clas = clazz; clas != NULL; clas = clas->superclass) { Field *fld = CLASS_FIELDS(clas); for (i = CLASS_NFIELDS(clas)-1; i >= 0; i--) { if (fld[i].accflags & ACC_PUBLIC) { count++; } } } for (i = 0; i < clazz->total_interface_len; i++) { count += countPublicFields(clazz->interfaces[i]); } return (count);}static voidmakePublicFields(Hjava_lang_Class* clazz, jboolean declared, Hjava_lang_reflect_Field*** pptr){ Hjava_lang_Class* clas; Hjava_lang_reflect_Field** ptr = *pptr; int i; for (clas = clazz; clas != NULL; clas = clas->superclass) { Field *fld = CLASS_FIELDS(clas); for (i = CLASS_NFIELDS(clas)-1; i >= 0; i--) { if ((fld[i].accflags & ACC_PUBLIC) || declared) { *ptr = makeField(clas, i); ptr++; } } if (declared) { break; } } if (!declared) { for (i = 0; i < clazz->total_interface_len; i++) { makePublicFields(clazz->interfaces[i], declared, &ptr); } } *pptr = ptr;}/* * Below, "declared" means to include a field only if it is directly * declared by that class (and not inherited from a superclass or defined * by an interface the class implements.) This applies to both private, * protected, and public fields. * * On the other hand, if "declared" is false, we only include public * fields. Weird semantics. */HArrayOfObject*java_lang_Class_getFields0(struct Hjava_lang_Class* clazz, jboolean declared){ int count; Hjava_lang_reflect_Field** ptr; HArrayOfObject* array; if (declared) { count = CLASS_NFIELDS((Hjava_lang_Class*)clazz); } else { count = countPublicFields(clazz); } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/reflect/Field;", 0); ptr = (Hjava_lang_reflect_Field**)&unhand_array(array)->body[0]; makePublicFields(clazz, declared, &ptr); return (array);}/* * Check whether the parameters of Method `mth' have exactly the same * types as `argtypes', where argtypes is an array of Hjava_lang_Class * * * Note that checking the arguments might cause the resolution of names * that are part of the signature. These must be resolved by the same * classloader that loaded the class to which the method belongs. * * This function is used by getMethod0 and getConstructor0. * * Returns 1 if they are exactly the same, 0 if not. */staticintcheckParameters(Method* mth, HArrayOfObject* argtypes){ int i; errorInfo info; /* The JDK doc says and experimentation shows that a null second * parameter to all get(Declared){Method|Constructor} functions * is treated like passing an empty array "new Class [] {}" */ if (argtypes == NULL) { if (METHOD_NARGS(mth) == 0) { return (1); } else { return (0); } } if (ARRAY_SIZE(argtypes) != METHOD_NARGS(mth)) { return (0); } for (i = 0; i < ARRAY_SIZE(argtypes); i++) { Hjava_lang_Class* sigclass; sigclass = getClassFromSignaturePart(METHOD_ARG_TYPE(mth, i), mth->class->loader, &info); if (sigclass == 0) { discardErrorInfo(&info); return 0; } if (sigclass != (struct Hjava_lang_Class *)OBJARRAY_DATA(argtypes)[i]) { return (0); } } return (1);}/* Check whether the loading of the class has failed. Throw an NoClassDefFoundError in that the case.*/staticvoidcheckIfClassHasFailed(struct Hjava_lang_Class* clas){ if (clas != NULL && clas->state == CSTATE_FAILED) { SignalError("java.lang.NoClassDefFoundError", CLASS_CNAME(clas)); }}staticHjava_lang_reflect_Method*findMatchingMethod(struct Hjava_lang_Class* clas, struct Hjava_lang_String* name, HArrayOfObject* arr, jboolean declared){ Method* mth = CLASS_METHODS(clas); int n = CLASS_NMETHODS(clas); int i; for (i = 0; i < n; ++mth, ++i) { if (((mth->accflags & ACC_PUBLIC) || declared) && utf8ConstEqualJavaString(mth->name, name)) { if (checkParameters(mth, arr)) return (makeMethod(clas, i)); } } return (0);}Hjava_lang_reflect_Method*java_lang_Class_getMethod0(struct Hjava_lang_Class* this, struct Hjava_lang_String* name, HArrayOfObject* arr, jboolean declared){ Hjava_lang_Class* clas; Hjava_lang_reflect_Method *rmeth; clas = this; checkIfClassHasFailed(clas); do { rmeth = findMatchingMethod(clas, name, arr, declared); if (rmeth != 0) { return (rmeth); } clas = clas->superclass; } while (!declared && clas != NULL); /* If the class is an interface, check implemented interfaces as well. * Those are the interfaces this interface inherited */ if (CLASS_IS_INTERFACE(this)) { int i; for (i = 0; i < this->total_interface_len; i++) { rmeth = findMatchingMethod(this->interfaces[i], name, arr, declared); if (rmeth != 0) { return (rmeth); } } } /* like SignalError, except that the name of the class that is * not found becomes the error message */ throwException((struct Hjava_lang_Throwable*)execute_java_constructor( "java.lang.NoSuchMethodException", 0, 0, "(Ljava/lang/String;)V", name));}struct Hjava_lang_reflect_Constructor*java_lang_Class_getConstructor0(struct Hjava_lang_Class* this, HArrayOfObject* arr, jboolean declared){ Hjava_lang_Class* clas = this; Method* mth; int n; int i; checkIfClassHasFailed(clas); mth = CLASS_METHODS(clas); n = CLASS_NMETHODS(clas); for (i = 0; i < n; ++mth, ++i) { if (((mth->accflags & ACC_PUBLIC) || declared) && (METHOD_IS_CONSTRUCTOR(mth))) { if (checkParameters(mth, arr)) return (makeConstructor(clas, i)); } } SignalError("java.lang.NoSuchMethodException", ""); /* FIXME */}staticHjava_lang_reflect_Field*checkForField(struct Hjava_lang_Class* clazz, struct Hjava_lang_String* name, jboolean declared){ int i; Hjava_lang_Class* clas; /* first try this class's own or inherited fields */ clas = (Hjava_lang_Class*) clazz; do { Field* fld = CLASS_FIELDS(clas); int n = CLASS_NFIELDS(clas); int i; for (i = 0; i < n; ++fld, ++i) { if (((fld->accflags & ACC_PUBLIC) || declared) && utf8ConstEqualJavaString(fld->name, name)) { return makeField(clas, i); } } clas = clas->superclass; } while (!declared && clas != NULL); /* then try this class's interfaces fields using the wonders of * recursion. */ for (i = 0; i < clazz->total_interface_len; i++) { Hjava_lang_reflect_Field *f; f = checkForField(clazz->interfaces[i], name, declared); if (f != 0) { return (f); } } return (0);}Hjava_lang_reflect_Field*java_lang_Class_getField0(struct Hjava_lang_Class* clazz, struct Hjava_lang_String* name, jboolean declared){ Hjava_lang_reflect_Field* f = checkForField(clazz, name, declared); if (f != 0) { return (f); } /* like SignalError, except that the name of the field that is * not found becomes the error message */ throwException((struct Hjava_lang_Throwable*)execute_java_constructor( "java.lang.NoSuchFieldException", 0, 0, "(Ljava/lang/String;)V", name));}HArrayOfObject*java_lang_Class_getClasses0(struct Hjava_lang_Class* clazz, jboolean inner){ errorInfo einfo; int count; int i; innerClass *ic; Hjava_lang_Class* c; HArrayOfObject* array; Hjava_lang_Class** ptr; /* Lookup inner classes or outer class. An inner class have outer == clazz. An outer class have inner == clazz. */ count = 0; for (i = clazz->nr_inner_classes, ic = clazz->inner_classes; i-- > 0; ic++) { if (ic->inner_class == 0 || ic->outer_class == 0) { continue; }#if 0 c = getClass (inner ? ic->outer_class : ic->inner_class, clazz, &einfo); if (c == NULL) { throwError(&einfo); } if (c == clazz) { count++; }#else /* assume one unique constant pool entry per class */ if (clazz->this_index == (inner ? ic->outer_class : ic->inner_class)) { count++; }#endif } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/Class;", 0); if (count == 0) { return array; } ptr = (Hjava_lang_Class**)&unhand_array(array)->body[0]; for (i = clazz->nr_inner_classes, ic = clazz->inner_classes; i-- > 0; ic++) { if (ic->inner_class == 0 || ic->outer_class == 0) { continue; }#if 0 c = getClass (inner ? ic->outer_class : ic->inner_class, clazz, &einfo); if (c == NULL) { throwError(&einfo); } if (c != clazz) { continue; }#else /* assume one unique constant pool entry per class */ if (clazz->this_index != (inner ? ic->outer_class : ic->inner_class)) { continue; }#endif c = getClass (inner ? ic->inner_class : ic->outer_class, clazz, &einfo); if (c == NULL) { throwError(&einfo); } *ptr++ = c; } return array;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -