-/* class: java/lang/Class */
+/* src/native/vm/VMClass.c - java/lang/VMClass
+ 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
-#include "jni.h"
-#include "types.h"
-#include "global.h"
-#include "builtin.h"
-#include "loader.h"
-#include "native.h"
-#include "tables.h"
-#include "java_lang_Class.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"
+ This file is part of CACAO.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
-/* for selecting public members */
-#define MEMBER_PUBLIC 0
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Roman Obermaiser
+
+ Changes: Joseph Wenninger
+ Christian Thalinger
+
+ $Id: VMClass.c 4357 2006-01-22 23:33:38Z twisti $
+
+*/
+
+
+#include <string.h>
+
+#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 struct java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, struct 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 (!name)
+ return NULL;
- if (runverbose) {
- log_text("Java_java_lang_VMClass_forName called");
- log_text(javastring_tochar((java_objectheader*)s));
+ /* 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;
+ }
}
- /* illegal argument */
- if (!s) return NULL;
-
- /* create utf string in which '.' is replaced by '/' */
- u = javastring_toutf(s, true);
-
- c = loader_load(u);
- if (c == NULL) {
- /* class was not loaded. raise exception */
- if (! exceptionptr) {
- if (runverbose)
- log_text("Setting class not found exception");
- exceptionptr =
- native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
+ /* create utf string in which '.' is replaced by '/' */
+
+ u = javastring_toutf(name, true);
+
+ /* try to load, ... */
+
+ 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_java_lang_NoClassDefFoundError) {
+ /* clear exceptionptr, because builtin_new checks for
+ ExceptionInInitializerError */
+ *exceptionptr = NULL;
+
+ *exceptionptr =
+ new_exception_javastring(string_java_lang_ClassNotFoundException, name);
}
- return NULL;
+ return NULL;
}
- /*log_text("Returning class");*/
- use_class_as_object (c);
- return (java_lang_Class*) c;
+
+ /* link, ... */
+
+ if (!link_class(c))
+ return NULL;
+
+ /* ...and initialize it, if required */
+
+ 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 struct java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader (JNIEnv *env , struct java_lang_VMClass* this )
-{
- init_systemclassloader();
- return 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 (java_lang_ClassLoader *) c->classloader;
}
+
/*
- * Class: java_lang_VMClass
- * Method: getModifiers
- * Signature: ()I
+ * Class: java/lang/VMClass
+ * Method: getComponentType
+ * Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType (JNIEnv *env , struct java_lang_VMClass* this )
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *thisclass = (classinfo*) (this->vmData);
- 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 , struct java_lang_VMClass* this , 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 *) (this->vmData);
- 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>");
+ 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;
+ c = (classinfo *) klass;
-
- log_text("Java_java_lang_VMClass_getDeclaredConstructors");
- log_plain_utf(c->name);
- log_plain("\n");
-/* class_showmethods(c);
- class_showmethods(loader_load(utf_new_char("java/lang/Class")));*/
+ /* determine number of constructors */
+ for (i = 0, public_methods = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- /* 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++;
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init))
+ public_methods++;
+ }
- class_constructor = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Constructor"));
- if (!class_constructor)
- return NULL;
+ oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
+ if (!oa)
+ return NULL;
- array_constructor = builtin_anewarray(public_methods, class_constructor);
+ for (i = 0, pos = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
- if (!array_constructor)
- return NULL;
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init)) {
- 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;
- o = native_new_and_init(class_constructor);
- array_constructor->data[pos++] = o;
-
- /* array of exceptions declared to be thrown, information not available !! */
- exceptiontypes = builtin_anewarray (0, class_java_lang_Class);
-
-/* 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));
- }
-
-log_text("leaving Java_java_lang_VMClass_getDeclaredConstructors");
-return array_constructor;
+ if (!(o = native_new_and_init(class_java_lang_reflect_Constructor)))
+ return NULL;
+
+ /* initialize instance fields */
+
+ rc = (java_lang_reflect_Constructor *) o;
+ rc->clazz = (java_lang_Class *) c;
+ rc->slot = i;
+ /* store object into array */
+ oa->data[pos++] = o;
+ }
+ }
-/* panic("Java_java_lang_Class_getConstructors0 called");
- return NULL;*/
+ 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 , struct java_lang_VMClass* this , s4 publicOnly)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 publicOnly)
{
-#warning fix the public only case
- classinfo *c = (classinfo *) (this->vmData);
- 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 (!this)
- return NULL;
-
- if (!this->vmData)
- return NULL;
-
- /*printf("PublicOnly: %d\n",publicOnly);*/
- if (!Java_java_lang_VMClass_isPrimitive(env, c) && (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 */
- declaredclasscount++;
- }
- }
-
- /*class_showmethods(c); */
-
- result = 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;
- }
- }
-
- return result;
+ 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++) {
+ 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++;
+ }
+ }
+
+ /* allocate Class[] and check for OOM */
+
+ oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+
+ 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 oa;
}
+
/*
- * Class: java/lang/Class
+ * Class: java/lang/VMClass
* Method: getDeclaringClass
* Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass ( JNIEnv *env , struct java_lang_VMClass* this)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
-#warning fixme
- classinfo *c = (classinfo *) (this->vmData);
- log_text("Java_java_lang_VMClass_getDeclaringClass");
+ classinfo *c;
+ classref_or_classinfo inner;
+ utf *innername;
+ classinfo *outer;
+ s4 i;
- if (this && this->vmData && !Java_java_lang_VMClass_isPrimitive(env, this) && (c->name->text[0]!='[')) {
- int i;
+ c = (classinfo *) klass;
- if (c->innerclasscount == 0) /* no innerclasses exist */
- return NULL;
+ 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);
- return (java_lang_Class*) outer;
- }
- }
- }
-
- /* return NULL for arrayclasses and primitive classes */
- return NULL;
-}
+ for (i = 0; i < c->innerclasscount; i++) {
+ inner = c->innerclass[i].inner_class;
-/*
- * Class: java/lang/Class
- * Method: getField0
- * Signature: (Ljava/lang/String;I)Ljava/lang/reflect/Field;
- */
-JNIEXPORT struct java_lang_reflect_Field* JNICALL Java_java_lang_VMClass_getField0 ( JNIEnv *env , struct java_lang_VMClass* this, struct java_lang_String* name, s4 public_only)
-{
- classinfo *c, *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"));
- o = (java_lang_reflect_Field*) native_new_and_init(c);
-
- /* get fieldinfo entry */
- idx = class_findfield_index_approx((classinfo*) (this->vmData), javastring_toutf(name, false));
- if (idx<0) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
- return NULL;
- }
- f= &(((struct classinfo*)(this->vmData))->fields[idx]);
- if (f) {
+ /* check if inner_class is a classref or a real class and
+ get the class name from the structure */
- if ( public_only && !(f->flags & ACC_PUBLIC))
- {
- /* field is not public and public only had been requested*/
- exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException);
- return NULL;
+ 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;
+ }
+ }
}
- desc = f->descriptor;
- fieldtype = class_from_descriptor(desc->text,utf_end(desc),NULL,true);
- if (!fieldtype) return NULL;
-
- /* initialize instance fields */
- setfield_critical(c,o,"declaringClass", "Ljava/lang/Class;", jobject, (jobject) (this->vmData) /*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); */
- 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 for arrayclasses and primitive classes */
+
+ 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 , struct java_lang_VMClass* this , 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 *) (this->vmData);
- 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;
+ 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;
- /* determine number of fields */
- for (i = 0; i < c->fieldscount; i++)
- if ((c->fields[i].flags & ACC_PUBLIC) || (!public_only)) public_fields++;
+ c = (classinfo *) klass;
- class_field = loader_load(utf_new_char("java/lang/reflect/Field"));
+ /* determine number of fields */
- if (!class_field)
- return NULL;
+ for (i = 0, public_fields = 0; i < c->fieldscount; i++)
+ if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+ public_fields++;
- /* create array of fields */
- array_field = builtin_anewarray(public_fields, class_field);
+ /* create array of fields */
- /* creation of array failed */
- if (!array_field)
- return NULL;
+ oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
+
+ if (!oa)
+ return NULL;
+
+ /* get the fields and store in the array */
+
+ 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;
+
+ /* initialize instance fields */
- /* 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*) Java_java_lang_VMClass_getField0
- (env,
- this,
- (java_lang_String*) javastring_new(c->fields[i].name),
- public_only);
- return array_field;
+ 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 , struct java_lang_VMClass* this)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo*) (this->vmData);
- u4 i;
- java_objectarray *a = builtin_anewarray (c->interfacescount, class_java_lang_Class);
- if (!a) return NULL;
- for (i=0; i<c->interfacescount; i++) {
- use_class_as_object (c->interfaces[i]);
-
- a->data[i] = (java_objectheader*) c->interfaces[i];
- }
- return a;
-}
+ classinfo *c;
+ classinfo *ic;
+ java_objectarray *oa;
+ u4 i;
+ c = (classinfo *) klass;
-/*
- * Class: java/lang/Class
- * Method: getMethod0
- * Signature: (Ljava/lang/String;[Ljava/lang/Class;I)Ljava/lang/reflect/Method;
- */
-JNIEXPORT struct java_lang_reflect_Method* JNICALL Java_java_lang_VMClass_getMethod0 ( JNIEnv *env , struct java_lang_Class*
- this, struct java_lang_String* name, java_objectarray* types, s4 which)
-{
- classinfo *c;
- classinfo *clazz = (classinfo *) this;
- 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"));
- 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 = native_new_and_init (class_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;
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return NULL;
+
+ oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+
+ if (!oa)
+ return NULL;
+
+ for (i = 0; i < c->interfacescount; i++) {
+ ic = c->interfaces[i].cls;
+
+ oa->data[i] = (java_objectheader *) ic;
+ }
+
+ 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 , struct java_lang_VMClass* this , 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 *) this->vmData;
- 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"));
- 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;
+
+ 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. */
+
+ if (Java_java_lang_VMClass_isArray(env, clazz, klass))
+ return builtin_anewarray(0, class_java_lang_reflect_Method);
+
+ /* determine number of methods */
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)))
+ public_methods++;
+ }
-/* 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,this)) {
- return builtin_anewarray(0, class_method);
- }
+ oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
+ if (!oa)
+ return NULL;
- /* 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++;
+ for (i = 0, pos = 0; i < c->methodscount; i++) {
+ m = &c->methods[i];
-/*
- class_showmethods(class_method);
- panic("JOWENN");
-*/
-
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit))) {
- array_method = builtin_anewarray(public_methods, class_method);
+ if (!(o = native_new_and_init(class_java_lang_reflect_Method)))
+ return NULL;
- if (!array_method)
- return NULL;
+ /* initialize instance fields */
- 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) )
- )) {
-
- m = &c->methods[i];
- o = native_new_and_init(class_method);
- array_method->data[pos++] = o;
-
- /* array of exceptions declared to be thrown, information not available !! */
- exceptiontypes = builtin_anewarray (0, class_java_lang_Class);
-
-
- /* 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 , struct java_lang_VMClass* this)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
{
- classinfo *c = (classinfo *) (this->vmData);
- return c->flags;
-}
+ classinfo *c;
+ classref_or_classinfo inner;
+ classref_or_classinfo outer;
+ utf *innername;
+ s4 i;
-/*
- * Class: java/lang/Class
- * Method: getName
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT struct java_lang_String* JNICALL Java_java_lang_VMClass_getName ( JNIEnv *env , struct java_lang_VMClass* this) {
- u4 i;
- classinfo *c = (classinfo*) (this->vmData);
- java_lang_String *s = (java_lang_String*) javastring_new(c->name);
- 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] = '.';
- }
-
- return s;
-
+ c = (classinfo *) klass;
+
+ if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+ /* search for passed class as inner class */
+
+ for (i = 0; i < c->innerclasscount; i++) {
+ inner = c->innerclass[i].inner_class;
+ outer = c->innerclass[i].outer_class;
+
+ /* 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;
+ }
+ }
+ }
+
+ /* 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 struct java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNIEnv *env, jclass clazz, struct 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;
- s4 len;
- s4 i;
- if (runverbose) log_text("Java_java_lang_VMClass_getName");
-
- dimCnt=0;
- while ( *utf_ptr != desc_end ) {
- if (utf_nextu2(utf_ptr)=='[') dimCnt++;
- else break;
- }
- utf__ptr=(*utf_ptr)-1;
-
- len=0;
- 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) {
- len=dimCnt+strlen(c->name->text)-2;
- str=MNEW(char,len+1);
- strncpy(str,++utf__ptr,len-2*dimCnt);
- }
-
- dimCnt=len-2*dimCnt;
- str[len]=0;
- for (i=len-1;i>=dimCnt;i=i-2) {
- str[i]=']';
- str[i-1]='[';
- }
- s=(java_lang_String*)javastring_new(utf_new_char(str));
- MFREE(str,char,len+1);
-
- if (!s) return NULL;
+ classinfo *c;
+ java_lang_String *s;
+ u4 i;
- /* return string where '/' is replaced by '.' */
- for (i=0; i<s->value->header.size; i++) {
- if (s->value->data[i] == '/') s->value->data[i] = '.';
- }
-
- return s;
-}
+ c = (classinfo *) klass;
+ s = (java_lang_String *) javastring_new(c->name);
+ if (!s)
+ return NULL;
+ /* return string where '/' is replaced by '.' */
-/*
- * Class: java/lang/Class
- * Method: getProtectionDomain0
- * Signature: ()Ljava/security/ProtectionDomain;
- */
-JNIEXPORT struct java_security_ProtectionDomain* JNICALL Java_java_lang_VMClass_getProtectionDomain0 ( JNIEnv *env , struct java_lang_Class* this)
-{
- log_text("Java_java_lang_VMClass_getProtectionDomain0 called");
- return NULL;
-}
+ for (i = 0; i < s->value->header.size; i++) {
+ if (s->value->data[i] == '/')
+ s->value->data[i] = '.';
+ }
-/*
- * Class: java/lang/Class
- * Method: getSigners
- * Signature: ()[Ljava/lang/Object;
- */
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getSigners ( JNIEnv *env , struct java_lang_Class* this)
-{
- log_text("Java_java_lang_VMClass_getSigners called");
- return NULL;
+ return s;
}
+
/*
* Class: java/lang/Class
* Method: getSuperclass
* Signature: ()Ljava/lang/Class;
*/
-JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass ( JNIEnv *env , struct java_lang_VMClass* this)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *cl= ((classinfo*)this->vmData);
- classinfo *c=cl -> super;
+ classinfo *c;
+ classinfo *sc;
+
+ c = (classinfo *) klass;
+ sc = c->super.cls;
+
+ if (c->flags & ACC_INTERFACE)
+ return NULL;
- if (!c) return NULL;
+ if (!sc)
+ return NULL;
- use_class_as_object (c);
- return (java_lang_Class*) c;
+ return (java_lang_Class *) sc;
}
+
/*
* Class: java/lang/Class
* Method: isArray
* Signature: ()Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray ( JNIEnv *env , struct java_lang_VMClass* this)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo*) (this->vmData);
- return c->vftbl->arraydesc != NULL;
+ classinfo *c = (classinfo *) klass;
+
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return 0;
+
+ return (c->vftbl->arraydesc != NULL);
}
+
/*
* Class: java/lang/Class
* Method: isAssignableFrom
* Signature: (Ljava/lang/Class;)Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom ( JNIEnv *env , struct java_lang_VMClass* this, struct java_lang_Class* sup)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Class *c)
{
-#warning fixme
- log_text("Java_java_lang_VMClass_isAssignableFrom");
- if (!this) return 0;
- if (!sup) return 0;
- if (!this->vmData) {
- 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) (this->vmData));
+
+ 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);
}
+
/*
* Class: java/lang/Class
* Method: isInstance
* Signature: (Ljava/lang/Object;)Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance ( JNIEnv *env , struct java_lang_VMClass* this, struct 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*) (this->vmData);
- return (*env)->IsInstanceOf(env,(jobject) obj,clazz);
+ classinfo *c;
+ java_objectheader *ob;
+
+ c = (classinfo *) klass;
+ ob = (java_objectheader *) o;
+
+ if (!(c->state & CLASS_LINKED))
+ if (!link_class(c))
+ return 0;
+
+ return builtin_instanceof(ob, c);
}
+
/*
* Class: java/lang/Class
* Method: isInterface
* Signature: ()Z
*/
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface ( JNIEnv *env , struct java_lang_VMClass* this)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- classinfo *c = (classinfo*) this->vmData;
- if (c->flags & ACC_INTERFACE) return true;
- return false;
-}
+ classinfo *c;
-/*
- * Class: java/lang/Class
- * Method: isPrimitive
- * Signature: ()Z
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive ( JNIEnv *env , struct java_lang_VMClass* this)
-{
- int i;
- classinfo *c = (classinfo *) this->vmData;
+ c = (classinfo *) klass;
- /* search table of primitive classes */
- for (i=0;i<PRIMITIVETYPE_COUNT;i++)
- if (primitivetype_table[i].class_primitive == c) return true;
+ if (c->flags & ACC_INTERFACE)
+ return true;
- return false;
+ return false;
}
/*
* Class: java/lang/Class
- * Method: registerNatives
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_registerNatives ( JNIEnv *env )
-{
- /* empty */
-}
-
-/*
- * Class: java/lang/Class
- * Method: setProtectionDomain0
- * Signature: (Ljava/security/ProtectionDomain;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_setProtectionDomain0 ( JNIEnv *env , struct java_lang_Class* this, struct java_security_ProtectionDomain* par1)
-{
- if (verbose)
- log_text("Java_java_lang_VMClass_setProtectionDomain0 called");
-}
-
-/*
- * Class: java/lang/Class
- * Method: setSigners
- * Signature: ([Ljava/lang/Object;)V
+ * Method: isPrimitive
+ * Signature: ()Z
*/
-JNIEXPORT void JNICALL Java_java_lang_VMClass_setSigners ( JNIEnv *env , struct java_lang_Class* this, java_objectarray* par1)
+JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *klass)
{
- if (verbose)
- log_text("Java_java_lang_VMClass_setSigners called");
-}
+ 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;
+ return false;
+}
/*
- * Class: java_lang_VMClass
- * Method: initialize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize (JNIEnv *env , struct java_lang_VMClass* this ){
- log_text("Java_java_lang_VMClass_initialize");
-}
-/*
- * Class: java_lang_VMClass
- * Method: loadArrayClass
- * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
- */
-JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass (JNIEnv *env , jclass clazz, struct java_lang_String* par1, struct
- 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, struct java_lang_Throwable* par1) {
- log_text("Java_java_lang_VMClass_throwException");
-}
-
-/*
- * Class: java_lang_VMClass
- * Method: step7
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_step7 (JNIEnv *env , struct java_lang_VMClass* this ) {
- log_text("Java_java_lang_VMClass_step7");
-}
-/*
- * Class: java_lang_VMClass
- * Method: step8
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_step8 (JNIEnv *env , struct java_lang_VMClass* this ) {
- log_text("Java_java_lang_VMClass_step8");
+JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
+{
+ *exceptionptr = (java_objectheader *) t;
}
-
-/*
- * Class: java_lang_VMClass
- * Method: isInitialized
- * Signature: ()Z
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInitialized (JNIEnv *env , struct java_lang_VMClass* this ) {
- log_text("Java_java_lang_VMClass_isInitialized");
- return 1;
-}
/*
- * Class: java_lang_VMClass
- * Method: setInitialized
- * Signature: ()V
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
*/
-JNIEXPORT void JNICALL Java_java_lang_VMClass_setInitialized (JNIEnv *env , struct java_lang_VMClass* this ) {
- log_text("Java_java_lang_VMClass_setInitialized");
-}