-/* nat/VMClass.c - java/lang/Class
+/* src/native/vm/VMClass.c - java/lang/VMClass
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
- M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Roman Obermaiser
Changes: Joseph Wenninger
+ Christian Thalinger
- $Id: VMClass.c 1323 2004-07-18 21:42:11Z motse $
+ $Id: VMClass.c 4357 2006-01-22 23:33:38Z twisti $
*/
#include <string.h>
-#include "jni.h"
-#include "types.h"
-#include "global.h"
-#include "builtin.h"
-#include "loader.h"
-#include "native.h"
-#include "tables.h"
-#include "toolbox/logging.h"
-#include "toolbox/memory.h"
-#include "java_lang_Object.h"
-#include "java_lang_Class.h"
-#include "java_lang_ClassLoader.h"
-#include "java_security_ProtectionDomain.h"
-#include "java_lang_reflect_Constructor.h"
-#include "java_lang_reflect_Field.h"
-#include "java_lang_reflect_Method.h"
-#include "java_lang_Throwable.h" /* needed for java_lang_VMClass.h */
-#include "java_lang_VMClass.h"
-
-/* for selecting public members */
-#define MEMBER_PUBLIC 0
+#include "config.h"
+#include "vm/types.h"
+
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.h"
+#include "native/include/java_lang_Class.h"
+#include "native/include/java_lang_ClassLoader.h"
+#include "native/include/java_lang_Object.h"
+#include "native/include/java_lang_VMClass.h"
+#include "native/include/java_lang_reflect_Constructor.h"
+#include "native/include/java_lang_reflect_Field.h"
+#include "native/include/java_lang_reflect_Method.h"
+#include "native/include/java_security_ProtectionDomain.h"
+#include "toolbox/logging.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/initialize.h"
+#include "vm/loader.h"
+#include "vm/resolve.h"
+#include "vm/stringlocal.h"
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: forName
- * Signature: (Ljava/lang/String;)Ljava/lang/Class;
+ * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
*/
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *s)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
{
classinfo *c;
- utf *u;
+ utf *u;
+ u2 *pos;
+ s4 i;
/* illegal argument */
- if (!s)
+
+ if (!name)
return NULL;
-
+
+ /* name must not contain '/' (mauve test) */
+
+ for (i = 0, pos = name->value->data + name->offset; i < name->count; i++, pos++) {
+ if (*pos == '/') {
+ *exceptionptr =
+ new_exception_javastring(string_java_lang_ClassNotFoundException, name);
+ return NULL;
+ }
+ }
+
/* create utf string in which '.' is replaced by '/' */
- u = javastring_toutf(s, true);
- /* create a new class, ... */
- c = class_new(u);
+ u = javastring_toutf(name, true);
+
+ /* try to load, ... */
- /* load, ... */
- if (!class_load(c)) {
+ if (!(c = load_class_from_classloader(u, (java_objectheader *) loader))) {
classinfo *xclass;
xclass = (*exceptionptr)->vftbl->class;
/* if the exception is a NoClassDefFoundError, we replace it with a
ClassNotFoundException, otherwise return the exception */
- if (xclass == class_get(utf_new_char(string_java_lang_NoClassDefFoundError))) {
+ if (xclass == class_java_lang_NoClassDefFoundError) {
/* clear exceptionptr, because builtin_new checks for
ExceptionInInitializerError */
*exceptionptr = NULL;
*exceptionptr =
- new_exception_javastring(string_java_lang_ClassNotFoundException, s);
+ new_exception_javastring(string_java_lang_ClassNotFoundException, name);
}
return NULL;
}
/* link, ... */
- if (!class_link(c))
+
+ if (!link_class(c))
return NULL;
- /* ...and initialize it */
- if (!class_init(c))
- return NULL;
+ /* ...and initialize it, if required */
- use_class_as_object(c);
+ if (initialize)
+ if (!initialize_class(c))
+ return NULL;
return (java_lang_Class *) c;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getClassLoader
* Signature: ()Ljava/lang/ClassLoader;
*/
-JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *that)
-{
- return ((classinfo*)that)->classloader;
-/* init_systemclassloader();
+JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *klass)
+{
+ classinfo *c;
+
+ c = (classinfo *) klass;
- return SystemClassLoader;*/
+ return (java_lang_ClassLoader *) c->classloader;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getComponentType
* Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz,java_lang_Class *that)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *thisclass = (classinfo *) that;
- classinfo *c = NULL;
- arraydescriptor *desc;
-
- if ((desc = thisclass->vftbl->arraydesc) != NULL) {
- if (desc->arraytype == ARRAYTYPE_OBJECT)
- c = desc->componentvftbl->class;
- else
- c = primitivetype_table[desc->arraytype].class_primitive;
-
- /* set vftbl */
- use_class_as_object(c);
- }
-
- return (java_lang_Class *) c;
+ classinfo *c;
+ classinfo *comp;
+ arraydescriptor *desc;
+
+ c = (classinfo *) klass;
+ desc = c->vftbl->arraydesc;
+
+ if (desc == NULL)
+ return NULL;
+
+ if (desc->arraytype == ARRAYTYPE_OBJECT)
+ comp = desc->componentvftbl->class;
+ else
+ comp = primitivetype_table[desc->arraytype].class_primitive;
+
+ return (java_lang_Class *) comp;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getDeclaredConstructors
* Signature: (Z)[Ljava/lang/reflect/Constructor;
*/
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz,
- struct java_lang_Class *that, s4 public_only)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 publicOnly)
{
-
- classinfo *c = (classinfo *) that;
- java_objectheader *o;
- classinfo *class_constructor;
- java_objectarray *array_constructor; /* result: array of Method-objects */
- java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
- methodinfo *m; /* the current method to be represented */
- int public_methods = 0; /* number of public methods of the class */
- int pos = 0;
- int i;
- utf *utf_constr = utf_new_char("<init>");
-
- /* determine number of constructors */
- for (i = 0; i < c->methodscount; i++)
- if (((c->methods[i].flags & ACC_PUBLIC) || !public_only) &&
- (c->methods[i].name == utf_constr))
- public_methods++;
+ classinfo *c;
+ methodinfo *m; /* the current method to be represented */
+ java_objectarray *oa; /* result: array of Method-objects */
+ java_objectheader *o;
+ java_lang_reflect_Constructor *rc;
+ s4 public_methods; /* number of public methods of the class */
+ s4 pos;
+ s4 i;
- class_constructor = class_new(utf_new_char("java/lang/reflect/Constructor"));
+ c = (classinfo *) klass;
- if (!class_constructor->loaded)
- class_load(class_constructor);
+ /* determine number of constructors */
- if (!class_constructor->linked)
- class_link(class_constructor);
+ for (i = 0, public_methods = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- array_constructor = builtin_anewarray(public_methods, class_constructor);
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init))
+ public_methods++;
+ }
+
+ oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
- if (!array_constructor)
+ if (!oa)
return NULL;
- for (i = 0; i < c->methodscount; i++)
- if ((c->methods[i].flags & ACC_PUBLIC) || !public_only){
- m = &c->methods[i];
- if (m->name!=utf_constr)
- continue;
+ for (i = 0, pos = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- o = native_new_and_init(class_constructor);
- array_constructor->data[pos++] = o;
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init)) {
- /* array of exceptions declared to be thrown, information not available !! */
- exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
+ if (!(o = native_new_and_init(class_java_lang_reflect_Constructor)))
+ return NULL;
- /* class_showconstantpool(class_constructor);*/
/* initialize instance fields */
- /* ((java_lang_reflect_Constructor*)o)->flag=(m->flags & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED));*/
- setfield_critical(class_constructor,o,"clazz", "Ljava/lang/Class;", jobject, (jobject) c /*this*/);
- setfield_critical(class_constructor,o,"slot", "I", jint, i);
- /* setfield_critical(class_constructor,o,"flag", "I", jint, (m->flags & (ACC_PRIVATE |
- ACC_PUBLIC | ACC_PROTECTED))); */
- setfield_critical(class_constructor,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
- setfield_critical(class_constructor,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));
- }
-
- return array_constructor;
+
+ rc = (java_lang_reflect_Constructor *) o;
+
+ rc->clazz = (java_lang_Class *) c;
+ rc->slot = i;
+
+ /* store object into array */
+
+ oa->data[pos++] = o;
+ }
+ }
+
+ return oa;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getDeclaredClasses
* Signature: (Z)[Ljava/lang/Class;
*/
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 publicOnly)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 publicOnly)
{
-#if defined(__GNUC__)
-#warning fix the public only case
-#endif
- classinfo *c = (classinfo *) that;
- int pos = 0; /* current declared class */
- int declaredclasscount = 0; /* number of declared classes */
- java_objectarray *result; /* array of declared classes */
- int notPublicOnly = !publicOnly;
- int i;
-
- if (!that)
- return NULL;
-
- /*printf("PublicOnly: %d\n",publicOnly);*/
- if (!Java_java_lang_VMClass_isPrimitive(env, clazz, (java_lang_Class *) c) && (c->name->text[0] != '[')) {
+ classinfo *c;
+ classref_or_classinfo outer;
+ utf *outername;
+ s4 declaredclasscount; /* number of declared classes */
+ s4 pos; /* current declared class */
+ java_objectarray *oa; /* array of declared classes */
+ s4 i;
+
+ c = (classinfo *) klass;
+ declaredclasscount = 0;
+
+ if (!Java_java_lang_VMClass_isPrimitive(env, clazz, klass) &&
+ (c->name->text[0] != '[')) {
/* determine number of declared classes */
+
for (i = 0; i < c->innerclasscount; i++) {
- if ( (c->innerclass[i].outer_class == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
- /* outer class is this class */
+ outer = c->innerclass[i].outer_class;
+
+ /* check if outer_class is a classref or a real class and
+ get the class name from the structure */
+
+ outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+ /* outer class is this class */
+
+ if ((outername == c->name) &&
+ ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
declaredclasscount++;
}
}
- /*class_showmethods(c); */
+ /* allocate Class[] and check for OOM */
- result = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+ oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
- for (i = 0; i < c->innerclasscount; i++) {
- classinfo *inner = c->innerclass[i].inner_class;
- classinfo *outer = c->innerclass[i].outer_class;
-
- if ((outer == c) && (notPublicOnly || (inner->flags & ACC_PUBLIC))) {
- /* outer class is this class, store innerclass in array */
- use_class_as_object(inner);
- result->data[pos++] = (java_objectheader *) inner;
+ if (!oa)
+ return NULL;
+
+ for (i = 0, pos = 0; i < c->innerclasscount; i++) {
+ outer = c->innerclass[i].outer_class;
+
+ /* check if outer_class is a classref or a real class and
+ get the class name from the structure */
+
+ outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+ /* outer class is this class */
+
+ if ((outername == c->name) &&
+ ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
+ classinfo *inner;
+
+ if (!resolve_classref_or_classinfo(NULL,
+ c->innerclass[i].inner_class,
+ resolveEager, false, false,
+ &inner))
+ return NULL;
+
+ if (!(inner->state & CLASS_LINKED))
+ if (!link_class(inner))
+ return NULL;
+
+ oa->data[pos++] = (java_objectheader *) inner;
}
}
- return result;
+ return oa;
}
/*
- * Class: java/lang/Class
+ * Class: java/lang/VMClass
* Method: getDeclaringClass
* Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, struct java_lang_Class *that)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
-#if defined(__GNUC__)
-#warning fixme
-#endif
- classinfo *c = (classinfo *) that;
+ classinfo *c;
+ classref_or_classinfo inner;
+ utf *innername;
+ classinfo *outer;
+ s4 i;
+
+ c = (classinfo *) klass;
- if (that && !Java_java_lang_VMClass_isPrimitive(env, clazz,that) && (c->name->text[0] != '[')) {
- int i;
+ if (!Java_java_lang_VMClass_isPrimitive(env, clazz, klass) &&
+ (c->name->text[0] != '[')) {
if (c->innerclasscount == 0) /* no innerclasses exist */
return NULL;
for (i = 0; i < c->innerclasscount; i++) {
- classinfo *inner = c->innerclass[i].inner_class;
- classinfo *outer = c->innerclass[i].outer_class;
-
- if (inner == c) {
- /* innerclass is this class */
- use_class_as_object(outer);
+ inner = c->innerclass[i].inner_class;
+
+ /* check if inner_class is a classref or a real class and
+ get the class name from the structure */
+
+ innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+
+ /* innerclass is this class */
+
+ if (innername == c->name) {
+ /* maybe the outer class is not loaded yet */
+
+ if (!resolve_classref_or_classinfo(NULL,
+ c->innerclass[i].outer_class,
+ resolveEager, false, false,
+ &outer))
+ return NULL;
+
+ if (!(outer->state & CLASS_LINKED))
+ if (!link_class(outer))
+ return NULL;
+
return (java_lang_Class *) outer;
}
}
}
/* return NULL for arrayclasses and primitive classes */
- return NULL;
-}
-
-
-java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, s4 public_only)
-{
- classinfo *c;
- classinfo *fieldtype;
- fieldinfo *f; /* the field to be represented */
- java_lang_reflect_Field *o; /* result: field-object */
- utf *desc; /* the fielddescriptor */
- int idx;
-
- /* create Field object */
-/* c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Field")); */
- c = class_new(utf_new_char("java/lang/reflect/Field"));
- o = (java_lang_reflect_Field *) native_new_and_init(c);
-
- /* get fieldinfo entry */
- idx = class_findfield_index_approx((classinfo *) that, javastring_toutf(name, false));
-
- if (idx < 0) {
- *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
- return NULL;
- }
- f = &(((classinfo *) that)->fields[idx]);
- if (f) {
- if (public_only && !(f->flags & ACC_PUBLIC)) {
- /* field is not public and public only had been requested*/
- *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
- return NULL;
- }
-
- desc = f->descriptor;
- fieldtype = class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
- if (!fieldtype)
- return NULL;
-
- /* initialize instance fields */
- setfield_critical(c,o,"declaringClass", "Ljava/lang/Class;", jobject, (jobject) that /*this*/);
- /* ((java_lang_reflect_Field*)(o))->flag=f->flags;*/
- /* save type in slot-field for faster processing */
- /* setfield_critical(c,o,"flag", "I", jint, (jint) f->flags); */
- o->flag = f->flags;
- setfield_critical(c,o,"slot", "I", jint, (jint) idx);
- setfield_critical(c,o,"name", "Ljava/lang/String;", jstring, (jstring) name);
- /*setfield_critical(c,o,"type", "Ljava/lang/Class;", jclass, fieldtype);*/
-
- return o;
- }
-
- return NULL;
+ return NULL;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getDeclaredFields
* Signature: (Z)[Ljava/lang/reflect/Field;
*/
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 publicOnly)
{
- classinfo *c = (classinfo *) that;
- classinfo *class_field;
- java_objectarray *array_field; /* result: array of field-objects */
- int public_fields = 0; /* number of elements in field-array */
- int pos = 0;
- int i;
-
- /* determine number of fields */
- for (i = 0; i < c->fieldscount; i++)
- if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only))
+ classinfo *c;
+ java_objectarray *oa; /* result: array of field-objects */
+ fieldinfo *f;
+ java_objectheader *o;
+ java_lang_reflect_Field *rf;
+ s4 public_fields; /* number of elements in field-array */
+ s4 pos;
+ s4 i;
+
+ c = (classinfo *) klass;
+
+ /* determine number of fields */
+
+ for (i = 0, public_fields = 0; i < c->fieldscount; i++)
+ if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
public_fields++;
-/* class_field = loader_load(utf_new_char("java/lang/reflect/Field")); */
- class_field = class_new(utf_new_char("java/lang/reflect/Field"));
+ /* create array of fields */
+
+ oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
- if (!class_field)
+ if (!oa)
return NULL;
- /* create array of fields */
- array_field = builtin_anewarray(public_fields, class_field);
+ /* get the fields and store in the array */
- /* creation of array failed */
- if (!array_field)
- return NULL;
+ for (i = 0, pos = 0; i < c->fieldscount; i++) {
+ f = &(c->fields[i]);
+
+ if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+ /* create Field object */
+
+ if (!(o = native_new_and_init(class_java_lang_reflect_Field)))
+ return NULL;
- /* get the fields and store in the array */
- for (i = 0; i < c->fieldscount; i++)
- if ( (c->fields[i].flags & ACC_PUBLIC) || (!public_only))
- array_field->data[pos++] =
- (java_objectheader *) cacao_getField0(env,
- that, (java_lang_String *) javastring_new(c->fields[i].name),public_only);
- return array_field;
+ /* initialize instance fields */
+
+ rf = (java_lang_reflect_Field *) o;
+
+ rf->declaringClass = (java_lang_Class *) c;
+ rf->name = javastring_new(f->name);
+ rf->slot = i;
+
+ /* store object into array */
+
+ oa->data[pos++] = o;
+ }
+ }
+
+ return oa;
}
/*
- * Class: java/lang/Class
+ * Class: java/lang/VMClass
* Method: getInterfaces
* Signature: ()[Ljava/lang/Class;
*/
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo *) that;
- u4 i;
- java_objectarray *a;
+ classinfo *c;
+ classinfo *ic;
+ java_objectarray *oa;
+ u4 i;
+
+ c = (classinfo *) klass;
+
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return NULL;
- a = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+ oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
- if (!a)
+ if (!oa)
return NULL;
for (i = 0; i < c->interfacescount; i++) {
- use_class_as_object(c->interfaces[i]);
+ ic = c->interfaces[i].cls;
- a->data[i] = (java_objectheader *) c->interfaces[i];
+ oa->data[i] = (java_objectheader *) ic;
}
- return a;
-}
-
-
-java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, java_objectarray *types, s4 which)
-{
- classinfo *c;
- classinfo *clazz = (classinfo *) that;
- java_lang_reflect_Method* o; /* result: Method-object */
- java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
- methodinfo *m; /* the method to be represented */
-
-/* c = (classinfo *) loader_load(utf_new_char("java/lang/reflect/Method")); */
- c = class_new(utf_new_char("java/lang/reflect/Method"));
- o = (java_lang_reflect_Method *) native_new_and_init(c);
-
- /* find the method */
- m = class_resolvemethod_approx(clazz,
- javastring_toutf(name, false),
- create_methodsig(types,0)
- );
-
- if (!m || (which == MEMBER_PUBLIC && !(m->flags & ACC_PUBLIC))) {
- /* no apropriate method was found */
- *exceptionptr = new_exception(string_java_lang_NoSuchMethodException);
- return NULL;
- }
-
- /* array of exceptions declared to be thrown, information not available !! */
- exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
-
- /* initialize instance fields */
- setfield_critical(c,o,"clazz", "Ljava/lang/Class;", jobject, (jobject) clazz /*this*/);
- setfield_critical(c,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) types);
- setfield_critical(c,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
- setfield_critical(c,o,"name", "Ljava/lang/String;", jstring, javastring_new(m->name));
- setfield_critical(c,o,"modifiers", "I", jint, m->flags);
- setfield_critical(c,o,"slot", "I", jint, 0);
- setfield_critical(c,o,"returnType", "Ljava/lang/Class;", jclass, get_returntype(m));
-
- return o;
+ return oa;
}
/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: getDeclaredMethods
* Signature: (Z)[Ljava/lang/reflect/Method;
*/
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 publicOnly)
{
- classinfo *c = (classinfo *) that;
- java_objectheader *o;
- classinfo *class_method;
- java_objectarray *array_method; /* result: array of Method-objects */
- java_objectarray *exceptiontypes; /* the exceptions thrown by the method */
- methodinfo *m; /* the current method to be represented */
- int public_methods = 0; /* number of public methods of the class */
- int pos = 0;
- int i;
- utf *utf_constr=utf_new_char("<init>");
- utf *utf_clinit=utf_new_char("<clinit>");
-
-/* class_method = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Method")); */
- class_method = class_new(utf_new_char("java/lang/reflect/Method"));
-
- if (!class_method)
- return NULL;
+ classinfo *c;
+ java_objectheader *o;
+ java_lang_reflect_Method *rm;
+ java_objectarray *oa; /* result: array of Method-objects */
+ methodinfo *m; /* the current method to be represented */
+ s4 public_methods; /* number of public methods of the class */
+ s4 pos;
+ s4 i;
- /* JOWENN: array classes do not declare methods according to mauve test. It should be considered, if
- we should return to my old clone method overriding instead of declaring it as a member function */
- if (Java_java_lang_VMClass_isArray(env, clazz,that)) {
- return builtin_anewarray(0, class_method);
- }
+ c = (classinfo *) klass;
+ public_methods = 0;
+ /* JOWENN: array classes do not declare methods according to mauve
+ test. It should be considered, if we should return to my old
+ clone method overriding instead of declaring it as a member
+ function. */
- /* determine number of methods */
- for (i = 0; i < c->methodscount; i++)
- if ((((c->methods[i].flags & ACC_PUBLIC)) || (!public_only)) &&
- (!
- ((c->methods[i].name==utf_constr) ||
- (c->methods[i].name==utf_clinit) )
- )) public_methods++;
+ if (Java_java_lang_VMClass_isArray(env, clazz, klass))
+ return builtin_anewarray(0, class_java_lang_reflect_Method);
- /*
- class_showmethods(class_method);
- panic("JOWENN");
- */
-
+ /* determine number of methods */
- array_method = builtin_anewarray(public_methods, class_method);
+ for (i = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- if (!array_method)
- return NULL;
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)))
+ public_methods++;
+ }
- for (i = 0; i < c->methodscount; i++)
- if (((c->methods[i].flags & ACC_PUBLIC) || (!public_only)) &&
- (!
- ((c->methods[i].name==utf_constr) ||
- (c->methods[i].name==utf_clinit) )
- )) {
+ oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
- m = &c->methods[i];
- o = native_new_and_init(class_method);
- array_method->data[pos++] = o;
+ if (!oa)
+ return NULL;
+
+ for (i = 0, pos = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- /* array of exceptions declared to be thrown, information not available !! */
- exceptiontypes = builtin_anewarray (0, class_java_lang_Class);
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit))) {
+ if (!(o = native_new_and_init(class_java_lang_reflect_Method)))
+ return NULL;
/* initialize instance fields */
- /* ((java_lang_reflect_Method*)o)->flag=(m->flags &
- (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
- ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)
- );*/
- setfield_critical(class_method,o,"declaringClass", "Ljava/lang/Class;", jobject, (jobject) c /*this*/);
- setfield_critical(class_method,o,"name", "Ljava/lang/String;", jstring, javastring_new(m->name));
- /* setfield_critical(class_method,o,"flag", "I", jint, (m->flags &
- (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
- ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)));*/
- setfield_critical(class_method,o,"slot", "I", jint, i);
- /* setfield_critical(class_method,o,"returnType", "Ljava/lang/Class;", jclass, get_returntype(m));
- setfield_critical(class_method,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
- setfield_critical(class_method,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) get_parametertypes(m));*/
- }
-
- return array_method;
+
+ rm = (java_lang_reflect_Method *) o;
+
+ rm->declaringClass = klass;
+ rm->name = javastring_new(m->name);
+ rm->slot = i;
+
+ /* store object into array */
+
+ oa->data[pos++] = o;
+ }
+ }
+
+ return oa;
}
/*
- * Class: java/lang/Class
+ * Class: java/lang/VMClass
* Method: getModifiers
- * Signature: ()I
+ * Signature: (Z)I
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
{
- classinfo *c = (classinfo *) that;
- return c->flags;
-}
+ classinfo *c;
+ classref_or_classinfo inner;
+ classref_or_classinfo outer;
+ utf *innername;
+ s4 i;
+ c = (classinfo *) klass;
-/*
- * Class: java/lang/Class
- * Method: getName
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class* that)
-{
- u4 i;
- classinfo *c = (classinfo *) that;
- java_lang_String *s = (java_lang_String *) javastring_new(c->name);
+ if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+ /* search for passed class as inner class */
- if (!s)
- return NULL;
+ for (i = 0; i < c->innerclasscount; i++) {
+ inner = c->innerclass[i].inner_class;
+ outer = c->innerclass[i].outer_class;
- /* return string where '/' is replaced by '.' */
- for (i = 0; i < s->value->header.size; i++) {
- if (s->value->data[i] == '/')
- s->value->data[i] = '.';
+ /* Check if inner is a classref or a real class and get
+ the name of the structure */
+
+ innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+
+ /* innerclass is this class */
+
+ if (innername == c->name) {
+ /* has the class actually an outer class? */
+
+ if (outer.any)
+ /* return flags got from the outer class file */
+ return c->innerclass[i].flags;
+ else
+ return c->flags;
+ }
+ }
}
- return s;
-
+ /* passed class is no inner class or it was not requested */
+
+ return c->flags;
}
/*
* Class: java/lang/VMClass
- * Method: getBeautifiedName
- * Signature: (Ljava/lang/Class;)Ljava/lang/String;
+ * Method: getName
+ * Signature: ()Ljava/lang/String;
*/
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNIEnv *env, jclass clazz, java_lang_Class *par1)
+JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- u4 dimCnt;
- classinfo *c = (classinfo *) (par1);
-
- char *utf__ptr = c->name->text; /* current position in utf-text */
- char **utf_ptr = &utf__ptr;
- char *desc_end = utf_end(c->name); /* points behind utf string */
- java_lang_String *s;
- char *str = NULL;
- s4 len;
- s4 i;
-
-#if 0
- log_text("Java_java_lang_VMClass_getBeautifiedName");
- utf_display(c->name);
- log_text("beautifying");
-#endif
- dimCnt=0;
- while ( *utf_ptr != desc_end ) {
- if (utf_nextu2(utf_ptr)=='[') dimCnt++;
- else break;
- }
- utf__ptr = (*utf_ptr) - 1;
-
- len = 0;
-
-#if 0
- log_text("------>");
- utf_display(c->name);
- log_text("<------");
-#endif
-
- if (((*utf_ptr) + 1) == desc_end) {
- for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
- if (primitivetype_table[i].typesig == (*utf__ptr)) {
- len = dimCnt * 2 + strlen(primitivetype_table[i].name);
- str = MNEW(char, len + 1);
- strcpy(str, primitivetype_table[i].name);
- break;
- }
- }
- }
-
- if (len == 0) {
- if (dimCnt>0) {
- len = dimCnt + strlen(c->name->text) - 2;
- str = MNEW(char, len + 1);
- strncpy(str, ++utf__ptr, len - 2 * dimCnt);
- } else {
- len = strlen(c->name->text);
- str = MNEW(char, len + 1);
- strncpy(str, utf__ptr, len);
- }
-
- }
-
- dimCnt = len - 2 * dimCnt;
- str[len] = 0;
- for (i = len - 1; i >= dimCnt; i = i - 2) {
- str[i] = ']';
- str[i - 1] = '[';
- }
+ classinfo *c;
+ java_lang_String *s;
+ u4 i;
- s = javastring_new(utf_new_char(str));
- MFREE(str, char, len + 1);
+ c = (classinfo *) klass;
+ s = (java_lang_String *) javastring_new(c->name);
- if (!s) return NULL;
+ if (!s)
+ return NULL;
/* return string where '/' is replaced by '.' */
+
for (i = 0; i < s->value->header.size; i++) {
- if (s->value->data[i] == '/') s->value->data[i] = '.';
+ if (s->value->data[i] == '/')
+ s->value->data[i] = '.';
}
-
+
return s;
}
-
/*
* Class: java/lang/Class
* Method: getSuperclass
* Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *cl = (classinfo *) that;
- classinfo *c = cl->super;
+ classinfo *c;
+ classinfo *sc;
- if (!c)
+ c = (classinfo *) klass;
+ sc = c->super.cls;
+
+ if (c->flags & ACC_INTERFACE)
return NULL;
- use_class_as_object (c);
+ if (!sc)
+ return NULL;
- return (java_lang_Class *) c;
+ return (java_lang_Class *) sc;
}
* Method: isArray
* Signature: ()Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo *) that;
+ classinfo *c = (classinfo *) klass;
- return c->vftbl->arraydesc != NULL;
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return 0;
+
+ return (c->vftbl->arraydesc != NULL);
}
* Method: isAssignableFrom
* Signature: (Ljava/lang/Class;)Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Class *sup)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Class *c)
{
- /* log_text("Java_java_lang_VMClass_isAssignableFrom");*/
-
- if (!sup) return 0;
- if (!that) {
- panic("sup->vmClass is NULL in VMClass.isAssignableFrom");
+ classinfo *kc;
+ classinfo *cc;
+
+ kc = (classinfo *) klass;
+ cc = (classinfo *) c;
+
+ if (cc == NULL) {
+ exceptions_throw_nullpointerexception();
return 0;
}
- return (*env)->IsAssignableForm(env, (jclass) sup, (jclass) that);
+
+ if (!(kc->state & CLASS_LINKED))
+ if (!link_class(kc))
+ return 0;
+
+ if (!(cc->state & CLASS_LINKED))
+ if (!link_class(cc))
+ return 0;
+
+ /* XXX this may be wrong for array classes */
+
+ return builtin_isanysubclass(cc, kc);
}
* Method: isInstance
* Signature: (Ljava/lang/Object;)Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Object *obj)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Object *o)
{
-/* classinfo *clazz = (classinfo *) that; */
+ classinfo *c;
+ java_objectheader *ob;
+
+ c = (classinfo *) klass;
+ ob = (java_objectheader *) o;
- return (*env)->IsInstanceOf(env, (jobject) obj, that);
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return 0;
+
+ return builtin_instanceof(ob, c);
}
* Method: isInterface
* Signature: ()Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo *) that;
+ classinfo *c;
+
+ c = (classinfo *) klass;
if (c->flags & ACC_INTERFACE)
return true;
* Method: isPrimitive
* Signature: ()Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- int i;
- classinfo *c = (classinfo *) that;
+ classinfo *c;
+ s4 i;
+
+ c = (classinfo *) klass;
/* search table of primitive classes */
+
for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
if (primitivetype_table[i].class_primitive == c)
return true;
/*
- * Class: java_lang_VMClass
- * Method: initialize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *c)
-{
- classinfo *ci;
-
- ci = (classinfo *) c;
-
- /* initialize class */
- if (!ci->initialized)
- class_init(ci);
-}
-
-
-/*
- * Class: java_lang_VMClass
- * Method: loadArrayClass
- * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_ClassLoader* par2)
-{
- log_text("Java_java_lang_VMClass_loadArrayClass");
-
- return 0;
-}
-
-
-/*
- * Class: java_lang_VMClass
+ * Class: java/lang/VMClass
* Method: throwException
* Signature: (Ljava/lang/Throwable;)V
*/
-JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *par1)
+JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
{
- log_text("Won't implement VmClass.throwException. (Not needed according to spec) Is only needed to be bug compatible with the SUN VM. (according to gnuclasspath team)");
+ *exceptionptr = (java_objectheader *) t;
}
-
-
-
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where