class.c
来自「java virtual machince kaffe」· C语言 代码 · 共 680 行 · 第 1/2 页
C
680 行
/* * 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 "gtypes.h"#include "access.h"#include "baseClasses.h"#include "classMethod.h"#include "constants.h"#include "exception.h"#include "itypes.h"#include "lookup.h"#include "object.h"#include "soft.h"#include "stackTrace.h"#include "stringSupport.h"#include "support.h"#include "reflect.h"#include "access.h"#include "java_lang_reflect_Constructor.h"#include "java_lang_reflect_Method.h"#include "java_lang_reflect_Field.h"#include "java_lang_VMClass.h"#include "defs.h"/* * Convert string name to class object. */struct Hjava_lang_Class*java_lang_VMClass_forName(struct Hjava_lang_String* str, jboolean initialize, struct 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 (initialize && processClass(clazz, CSTATE_COMPLETE, &einfo) == false) { throwError(&einfo); } return (clazz);}struct Hjava_lang_Class*java_lang_VMClass_loadArrayClass(struct Hjava_lang_String* str, struct 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); } } /* Convert string to utf8, converting '.' to '/' */ utf8buf = checkPtr(stringJava2Utf8ConstReplace(str, '.', '/')); buf = utf8buf->data; clazz = loadArray(utf8buf, loader, &einfo); /* if an error occurred, throw an exception */ if (clazz == 0) { utf8ConstRelease(utf8buf); throwError(&einfo); } utf8ConstRelease(utf8buf); return clazz;}voidjava_lang_VMClass_initialize(struct Hjava_lang_Class* c){ errorInfo einfo; if (processClass(c, CSTATE_COMPLETE, &einfo) == false) { throwError(&einfo); }}/* * Convert class to string name. */struct Hjava_lang_String*java_lang_VMClass_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_VMClass_getSuperclass(struct Hjava_lang_Class* this){ if (!CLASS_IS_INTERFACE(this)) return (this->superclass); else return (NULL);}HArrayOfObject* /* [Ljava.lang.Class; */java_lang_VMClass_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;", NULL); 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_VMClass_getClassLoader(struct Hjava_lang_Class* this){ return (this->loader);}/* * Is the class an interface? */jbooleanjava_lang_VMClass_isInterface(struct Hjava_lang_Class* this){ return ((this->accflags & ACC_INTERFACE) ? 1 : 0);}jbooleanjava_lang_VMClass_isPrimitive(struct Hjava_lang_Class* this){ return (CLASS_IS_PRIMITIVE(this));}jbooleanjava_lang_VMClass_isArray(struct Hjava_lang_Class* this){ return (CLASS_IS_ARRAY(this));}Hjava_lang_Class*java_lang_VMClass_getComponentType(struct Hjava_lang_Class* this){ if (CLASS_IS_ARRAY(this)) { return (Kaffe_get_array_element_type(this)); } else { return ((Hjava_lang_Class*)NULL); }}jbooleanjava_lang_VMClass_isAssignableFrom(struct Hjava_lang_Class* this, struct Hjava_lang_Class* cls){ if (cls == NULL) return false; return (instanceof(this, cls));}/* * Is object instance of this class? */jbooleanjava_lang_VMClass_isInstance(struct Hjava_lang_Class* this, struct Hjava_lang_Object* obj){ return (soft_instanceof(this, obj));}jintjava_lang_VMClass_getModifiers(struct Hjava_lang_Class* this, jboolean ignoreInnerClassAttribute){#ifndef ACC_SUPER#define ACC_SUPER ACC_SYNCHRONISED#endif accessFlags accflags = this->accflags; if (this->this_inner_index >= 0 && !ignoreInnerClassAttribute) { assert(this->inner_classes != NULL); accflags = this->inner_classes[this->this_inner_index].inner_class_accflags; } return accflags & (ACC_MASK & ~ACC_SUPER);}HArrayOfObject*java_lang_VMClass_getDeclaredMethods(struct Hjava_lang_Class* clazz, jboolean publicOnly){ int count; Hjava_lang_reflect_Method** ptr; HArrayOfObject* array; int i; Method *mth = Kaffe_get_class_methods(clazz); count = 0; for (i = CLASS_NMETHODS(clazz)-1; i >= 0; i--) { if (publicOnly && ((mth[i].accflags&ACC_PUBLIC)==0)) continue; if ((mth[i].kFlags & KFLAG_CONSTRUCTOR)!=0) continue; if (utf8ConstEqual(init_name, mth[i].name)) continue; count++; } array = (HArrayOfObject*) AllocObjectArray(count, "Ljava/lang/reflect/Method;", NULL); ptr = (Hjava_lang_reflect_Method**)&unhand_array(array)->body[0]; for (i = CLASS_NMETHODS(clazz)-1; i >= 0; i--) { if (publicOnly && ((mth[i].accflags&ACC_PUBLIC)==0)) continue; if ((mth[i].kFlags & KFLAG_CONSTRUCTOR)!=0) continue;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?