?? class.c
字號:
/* * java.lang.Class.c * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-mem.h"#include "../../../kaffe/kaffevm/gtypes.h"#include "../../../kaffe/kaffevm/access.h"#include "../../../kaffe/kaffevm/baseClasses.h"#include "../../../kaffe/kaffevm/classMethod.h"#include "../../../kaffe/kaffevm/constants.h"#include "../../../kaffe/kaffevm/gtypes.h"#include "../../../kaffe/kaffevm/exception.h"#include "../../../kaffe/kaffevm/itypes.h"#include "../../../kaffe/kaffevm/lookup.h"#include "../../../kaffe/kaffevm/object.h"#include "../../../kaffe/kaffevm/soft.h"#include "../../../kaffe/kaffevm/stackTrace.h"#include "../../../kaffe/kaffevm/stringSupport.h"#include "../../../kaffe/kaffevm/support.h"#include "java_io_InputStream.h"#include "java_io_PrintStream.h"#include "java_lang_System.h"#include "java_lang_reflect_Constructor.h"#include "java_lang_reflect_Method.h"#include "java_lang_reflect_Field.h"#include "java_lang_Class.h"#include "defs.h"extern Hjava_lang_Object* buildStackTrace(struct _exceptionFrame*);/* * Convert string name to class object. */struct Hjava_lang_Class*java_lang_Class_forName(struct Hjava_lang_String* str, jbool doinit, Hjava_lang_ClassLoader* loader){ errorInfo einfo; Hjava_lang_Class* clazz; Utf8Const *utf8buf; const char *buf; int jlen; jchar *js; /* * NB: internally, we store class names as path names (with slashes * instead of dots. However, we must also prevent calls to * "java/lang/Object" or "[[Ljava/lang/Object;" from succeeding. * Since class names cannot have slashes, we reject all attempts * to look up names that do. Awkward. Inefficient. */ js = STRING_DATA(str); jlen = STRING_SIZE(str); while (--jlen > 0) { if (*js++ == '/') { postExceptionMessage(&einfo, JAVA_LANG(ClassNotFoundException), "Cannot have slashes - use dots instead."); throwError(&einfo); } } /* * Note the following oddity: * * It is apparently perfectly legal to call forName for array types, * such as "[Ljava.lang.String;" or "[B". * However, it is wrong to call Class.forName("Ljava.lang.String;") * * This situation is similar to the constant pool resolution. We * therefore do the same thing as in getClass in kaffevm/lookup.c, * that is, use either loadArray or loadClass depending on the name. * * This is somewhat described in Section 5.1.3 of the VM * Specification, titled "Array Classes". This section seems to * imply that we must avoid asking a class loader to resolve such * array names (those starting with an [), and this is what calling * loadArray does. */ /* Convert string to utf8, converting '.' to '/' */ utf8buf = checkPtr(stringJava2Utf8ConstReplace(str, '.', '/')); buf = utf8buf->data; if (buf[0] == '[') { clazz = loadArray(utf8buf, loader, &einfo); } else { clazz = loadClass(utf8buf, loader, &einfo); } /* if an error occurred, throw an exception */ if (clazz == 0) { utf8ConstRelease(utf8buf); throwError(&einfo); } utf8ConstRelease(utf8buf); /* * loadClass returns the class in state CSTATE_LINKED. * * Processing to CSTATE_COMPLETE will initialize the class, resolve * its constants and run its static initializers. * * The option to load a class via forName without initializing it * was introduced in 1.2, presumably for the convenience of * programs such as stub compilers. */ if (doinit && processClass(clazz, CSTATE_COMPLETE, &einfo) == false) { throwError(&einfo); } return (clazz);}/* * Convert class to string name. */struct Hjava_lang_String*java_lang_Class_getName(struct Hjava_lang_Class* c){ return(checkPtr(utf8Const2JavaReplace(c->name, '/', '.')));}/* * Return super class. * * Note that the specs demands to return null if the class object is an * interface or the class object representing java.lang.Object. * * That is, we're asked to NOT report superinterfaces for interfaces. * That would be impossible anyway since the spec says that the super_class * attribute in a class file describing an interface must point to * java.lang.Object. An interface is considered to "implement" its * superinterface(s). See also getInterfaceMethods0. */struct Hjava_lang_Class*java_lang_Class_getSuperclass(struct Hjava_lang_Class* this){ if (!CLASS_IS_INTERFACE(this)) return (this->superclass); else return (NULL);}HArrayOfObject* /* [Ljava.lang.Class; */java_lang_Class_getInterfaces(struct Hjava_lang_Class* this){ HArrayOfObject* obj; struct Hjava_lang_Class** ifaces; int i; int nr; nr = this->interface_len;#if defined(JDK_1_1_COMPAT) /* * Do not report java.io.Serializable for array classes in JDK 1.1 */ if (CLASS_IS_ARRAY(this)) { nr = 0; }#endif obj = (HArrayOfObject*)AllocObjectArray(nr, "Ljava/lang/Class;", 0); ifaces = (struct Hjava_lang_Class**)unhand_array(obj)->body; for (i = 0; i < nr; i++) { ifaces[i] = this->interfaces[i]; } return (obj);}/* * Return the class loader which loaded me. */struct Hjava_lang_ClassLoader*java_lang_Class_getClassLoader0(struct Hjava_lang_Class* this){ return (this->loader);}/* * Is the class an interface? */jbooljava_lang_Class_isInterface(struct Hjava_lang_Class* this){ return ((this->accflags & ACC_INTERFACE) ? 1 : 0);}jbooljava_lang_Class_isPrimitive(struct Hjava_lang_Class* this){ return (CLASS_IS_PRIMITIVE(this));}jbooljava_lang_Class_isArray(struct Hjava_lang_Class* this){ return (CLASS_IS_ARRAY(this));}Hjava_lang_Class*java_lang_Class_getComponentType(struct Hjava_lang_Class* this){ if (CLASS_IS_ARRAY(this)) { return (CLASS_ELEMENT_TYPE(this)); } else { return ((Hjava_lang_Class*)0); }}jbooljava_lang_Class_isAssignableFrom(struct Hjava_lang_Class* this, struct Hjava_lang_Class* cls){ return (instanceof(this, cls));}/* * Get primitive class from class name (JDK 1.1) */struct Hjava_lang_Class*java_lang_Class_getPrimitiveClass(struct Hjava_lang_String* name){ jchar* chrs; chrs = STRING_DATA(name); switch (chrs[0]) { case 'b': if (chrs[1] == 'y') { return (byteClass); } if (chrs[1] == 'o') { return (booleanClass); } break; case 'c': return (charClass); case 'd': return (doubleClass); case 'f': return (floatClass); case 'i': return (intClass); case 'l': return (longClass); case 's': return (shortClass); case 'v': return (voidClass); } return(NULL);}/* * Is object instance of this class? */jbooljava_lang_Class_isInstance(struct Hjava_lang_Class* this, struct Hjava_lang_Object* obj){ return (soft_instanceof(this, obj));}jintjava_lang_Class_getModifiers(struct Hjava_lang_Class* this){#ifndef ACC_SUPER#define ACC_SUPER ACC_SYNCHRONISED#endif return (this->accflags & (ACC_MASK & ~ACC_SUPER));}HArrayOfObject*java_lang_Class_getSigners(struct Hjava_lang_Class* this){ unimp("java.lang.Class:getSigners unimplemented");}voidjava_lang_Class_setSigners(struct Hjava_lang_Class* this, HArrayOfObject* sigs){ unimp("java.lang.Class:setSigners unimplemented");}static HArrayOfObject*makeParameters(Method* meth){ int i; HArrayOfObject* array; errorInfo info; Hjava_lang_Class* clazz; array = (HArrayOfObject*)AllocObjectArray(METHOD_NARGS(meth), "Ljava/lang/Class;", 0); for (i = 0; i < METHOD_NARGS(meth); ++i) { clazz = getClassFromSignaturePart(METHOD_ARG_TYPE(meth, i), meth->class->loader, &info); if (clazz == 0) { throwError(&info); } unhand_array(array)->body[i] = &clazz->head; } return (array);}static Hjava_lang_Class*makeReturn(Method* meth){ errorInfo info; Hjava_lang_Class* clazz; clazz = getClassFromSignaturePart(METHOD_RET_TYPE(meth), meth->class->loader, &info); if (clazz == 0) { throwError(&info); } return (clazz);}/* * create an array of types for the checked exceptions that this method * declared to throw. These are stored in the declared_exception table * as indices into the constant pool. * * We do not bother to cache the resolved types here. */static HArrayOfObject*makeExceptions(Method* meth){ int nr; int i; HArrayOfObject* array; Hjava_lang_Class** ptr; if( meth->ndeclared_exceptions == -1 ) { meth = meth->declared_exceptions_u.remote_exceptions; } nr = meth->ndeclared_exceptions; array = (HArrayOfObject*)AllocObjectArray(nr, "Ljava/lang/Class;", 0); ptr = (Hjava_lang_Class**)&unhand_array(array)->body[0]; for (i = 0; i < nr; i++) { errorInfo info; Hjava_lang_Class* clazz; clazz = getClass(meth->declared_exceptions[i], meth->class, &info); if (clazz == 0) { throwError(&info); } *ptr++ = clazz; } return (array);}staticHjava_lang_reflect_Constructor*makeConstructor(struct Hjava_lang_Class* clazz, int slot){ Hjava_lang_reflect_Constructor* meth; Method* mth; mth = CLASS_METHODS(clazz) + slot; meth = (Hjava_lang_reflect_Constructor*) AllocObject("java/lang/reflect/Constructor", 0); unhand(meth)->clazz = clazz; unhand(meth)->slot = slot; unhand(meth)->parameterTypes = makeParameters(mth); unhand(meth)->exceptionTypes = makeExceptions(mth); return (meth);}staticHjava_lang_reflect_Method*makeMethod(struct Hjava_lang_Class* clazz, int slot){ Hjava_lang_reflect_Method* meth; Method* mth; mth = CLASS_METHODS(clazz) + slot; meth = (Hjava_lang_reflect_Method*) AllocObject("java/lang/reflect/Method", 0); unhand(meth)->clazz = clazz; unhand(meth)->slot = slot; unhand(meth)->name = checkPtr(utf8Const2Java(mth->name)); unhand(meth)->parameterTypes = makeParameters(mth); unhand(meth)->exceptionTypes = makeExceptions(mth); unhand(meth)->returnType = makeReturn(mth); return (meth);}staticHjava_lang_reflect_Field*makeField(struct Hjava_lang_Class* clazz, int slot){ Hjava_lang_reflect_Field* field; Field* fld; errorInfo info; fld = CLASS_FIELDS(clazz) + slot; field = (Hjava_lang_reflect_Field*) AllocObject("java/lang/reflect/Field", 0); unhand(field)->clazz = clazz; unhand(field)->slot = slot; unhand(field)->type = resolveFieldType(fld, clazz, &info); if (unhand(field)->type == 0) { throwError(&info); } unhand(field)->name = checkPtr(utf8Const2Java(fld->name)); return (field);}/* * Return true if there is method defined in any subclass of 'cls' * that overrides 'meth'. * * Assumes that base is a subclass of cls */static intisOverridden(Hjava_lang_Class *base, Hjava_lang_Class *cls, Method *meth){ /* XXX for interfaces for now */ if (base == 0) return (false); /* Search superclasses for equivalent method name. * If found extract its index nr. */ for (; base != cls; base = base->superclass) { int j = CLASS_NMETHODS(base); Method* mt = CLASS_METHODS(base); for (; --j >= 0; ++mt) { if (utf8ConstEqual (mt->name, meth->name) && utf8ConstEqual (METHOD_SIG(mt), METHOD_SIG(meth))) { return (true); } } } return (false);}/* * count the number of methods in a class that are not constructors. * If declared is not set, count only public methods. */static intcountMethods(Hjava_lang_Class* base, Hjava_lang_Class* clas, jint declared){ 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){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -