X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fvm%2FVMClass.c;h=6ca26c0af31dd6678dcf288f6a83dbbf4ba24805;hb=ad92477479aeed17382996ab43a7ca0dfab2ba93;hp=f252bac8450313ba9b85f667c315dd7a14480a0f;hpb=38b85dc3786bd7af90feaf5ad17cd5389046e21d;p=cacao.git diff --git a/src/native/vm/VMClass.c b/src/native/vm/VMClass.c index f252bac84..6ca26c0af 100644 --- a/src/native/vm/VMClass.c +++ b/src/native/vm/VMClass.c @@ -1,804 +1,755 @@ -/* 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 + +#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(""); + 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; iinterfacescount; 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(""); - utf *utf_clinit=utf_new_char(""); - - - 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; ivalue->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;iname->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; ivalue->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;iflags & 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"); -}