Reversed vftbl movement because of performance considerations
[cacao.git] / nat / Class.c
index 3640598cd982bff4fd44c40053e63e354897aa87..9d637451a509dc44d05239155a473a1d4c99afdf 100644 (file)
@@ -238,12 +238,18 @@ classinfo *get_returntype(methodinfo *m)
  * Method:    forName0
  * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
  */
-JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_Class_forName0 ( JNIEnv *env ,  struct java_lang_String* s, s4 initialize, struct java_lang_ClassLoader* par3)
+JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_Class_forName0 ( JNIEnv *env ,  struct java_lang_String* s, s4 initialize, struct java_lang_ClassLoader* loader)
 {
        classinfo *c;
        utf *u;
        u4 i;
 
+       if (runverbose)
+       {
+           log_text("Java_java_lang_Class_forName0 called");
+           log_text(javastring_tochar((java_objectheader*)s));
+       }
+
        /* illegal argument */
        if (!s) return NULL;
        
@@ -251,6 +257,7 @@ JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_Class_forName0 ( JNIEnv
 
          /*  arrayclasses, e.g. [Ljava.lang.String; */   
          c = create_array_class(javastring_toutf(s, true));
+         assert(c != 0);
 
        } else
        {
@@ -259,12 +266,29 @@ JNIEXPORT struct java_lang_Class* JNICALL Java_java_lang_Class_forName0 ( JNIEnv
          u = javastring_toutf(s, true);
 
          if ( !(c = class_get(u)) ) {
-
-           /* class was not found, raise exception */
-           exceptionptr = 
-             native_new_and_init (class_java_lang_ClassNotFoundException);
-
-           return NULL;
+             methodinfo *method;
+             java_lang_Class *class;
+
+             /* class was not found. first check whether we can load it */
+             method = class_findmethod(loader->header.vftbl->class,
+                                       utf_new_char("loadClass"),
+                                       utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;"));
+             if (method == NULL)
+             {
+                 log_text("could not find method");
+                 exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
+                 return NULL;
+             }
+
+             c = (classinfo*)asm_calljavafunction(method, loader, s, NULL, NULL);
+
+             if (c == NULL)
+             {
+                 /* class was not loaded. raise exception */
+                 exceptionptr = 
+                     native_new_and_init (class_java_lang_ClassNotFoundException);
+                 return NULL;
+             }
          }
         }
 
@@ -487,7 +511,7 @@ JNIEXPORT struct java_lang_reflect_Field* JNICALL Java_java_lang_Class_getField0
       /* save type in slot-field for faster processing */
       setfield_critical(c,o,"slot",           "I",                 jint,    (jint) f->descriptor->text[0]);  
       setfield_critical(c,o,"name",           "Ljava/lang/String;", jstring, (jstring) name);
-      setfield_critical(c,o,"type",           "Ljava/lang/Class;",  jclass,  c);
+      setfield_critical(c,o,"type",           "Ljava/lang/Class;",  jclass,  fieldtype);
 
       return o;
     }
@@ -817,20 +841,20 @@ JNIEXPORT struct java_lang_Object* JNICALL Java_java_lang_Class_newInstance0 ( J
 {
        java_objectheader *o;
 
-       if (verbose) {  
-          char buffer[MAXSTRINGSIZE]; 
-         utf_sprint(buffer,((classinfo *) this)->name);      
-         strcat(buffer,"instantiated. ");
-         log_text(buffer);
-       }
+       if (verbose) {          
+               char buffer[MAXSTRINGSIZE]; 
+               utf_sprint(buffer,((classinfo *) this)->name);      
+               strcat(buffer," instantiated. ");
+               log_text(buffer);
+               }
        
        /* don't allow newInstance for array- and primitive classes */
 
        if (((classinfo *) this)->name->text[0]=='[')
-         panic("newInstance of array_class");
+               panic("newInstance of array_class");
 
        if (Java_java_lang_Class_isPrimitive(env,this))
-         panic("newInstance of primitive class");
+               panic("newInstance of primitive class");
 
        o = native_new_and_init ((classinfo*) this);