* Removed all Id tags.
[cacao.git] / src / native / native.c
index 9229f3a8bc106602a5c2230036bacba1cd06e31d..37f86f45c72fbd3da3442479f1440b929d0d0271 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: native.c 7911 2007-05-16 09:01:10Z twisti $
-
 */
 
 
 #include <assert.h>
 #include <ctype.h>
 
-#if !defined(WITH_STATIC_CLASSPATH)
+#if defined(ENABLE_LTDL) && defined(HAVE_LTDL_H)
 # include <ltdl.h>
 #endif
 
+#include <stdint.h>
+
 #include "vm/types.h"
 
 #include "mm/memory.h"
@@ -92,7 +92,10 @@ static bool nativecompdone = false;
 /* global variables ***********************************************************/
 
 static avl_tree_t *tree_native_methods;
+
+#if defined(ENABLE_LTDL)
 static hashtable *hashtable_library;
+#endif
 
 
 /* prototypes *****************************************************************/
@@ -108,7 +111,7 @@ static s4 native_tree_native_methods_comparator(const void *treenode, const void
 
 bool native_init(void)
 {
-#if !defined(WITH_STATIC_CLASSPATH)
+#if defined(ENABLE_LTDL)
        /* initialize libltdl */
 
        if (lt_dlinit())
@@ -125,10 +128,6 @@ bool native_init(void)
 
        tree_native_methods = avl_create(&native_tree_native_methods_comparator);
 
-       /* register the intern native functions */
-
-       nativevm_init();
-
        /* everything's ok */
 
        return true;
@@ -156,17 +155,26 @@ static s4 native_tree_native_methods_comparator(const void *treenode, const void
        treenmn = treenode;
        nmn     = node;
 
-       /* compare for avl_find if we have found an entry */
-
-       if (treenmn->name == nmn->name)
-               return 0;
-
        /* these are for walking the tree */
 
+       if (treenmn->classname < nmn->classname)
+               return -1;
+       else if (treenmn->classname > nmn->classname)
+               return 1;
+
        if (treenmn->name < nmn->name)
                return -1;
-       else
+       else if (treenmn->name > nmn->name)
                return 1;
+
+       if (treenmn->descriptor < nmn->descriptor)
+               return -1;
+       else if (treenmn->descriptor > nmn->descriptor)
+               return 1;
+
+       /* all pointers are equal, we have found the entry */
+
+       return 0;
 }
 
 
@@ -437,12 +445,13 @@ static utf *native_method_symbol(utf *classname, utf *methodname)
 
 *******************************************************************************/
 
-void native_method_register(utf *classname, JNINativeMethod *methods, s4 count)
+void native_method_register(utf *classname, const JNINativeMethod *methods,
+                                                       int32_t count)
 {
        native_methods_node_t *nmn;
-       utf                   *methodname;
        utf                   *name;
-       s4                     i;
+       utf                   *descriptor;
+       int32_t                i;
 
        /* insert all methods passed */
 
@@ -453,17 +462,19 @@ void native_method_register(utf *classname, JNINativeMethod *methods, s4 count)
                        printf(".%s]\n", methods[i].name);
                }
 
-               /* generate the method-symbol string */
+               /* generate the utf8 names */
 
-               methodname = utf_new_char(methods[i].name);
-               name       = native_method_symbol(classname, methodname);
+               name       = utf_new_char(methods[i].name);
+               descriptor = utf_new_char(methods[i].signature);
 
                /* allocate a new tree node */
 
                nmn = NEW(native_methods_node_t);
 
-               nmn->name   = name;
-               nmn->method = (functionptr) (ptrint) methods[i].fnPtr;
+               nmn->classname  = classname;
+               nmn->name       = name;
+               nmn->descriptor = descriptor;
+               nmn->function   = (functionptr) (ptrint) methods[i].fnPtr;
 
                /* insert the method into the tree */
 
@@ -478,19 +489,25 @@ void native_method_register(utf *classname, JNINativeMethod *methods, s4 count)
 
 *******************************************************************************/
 
-static functionptr native_method_find(utf *name)
+static functionptr native_method_find(methodinfo *m)
 {
        native_methods_node_t  tmpnmn;
        native_methods_node_t *nmn;
 
-       tmpnmn.name = name;
+       /* fill the temporary structure used for searching the tree */
+
+       tmpnmn.classname  = m->class->name;
+       tmpnmn.name       = m->name;
+       tmpnmn.descriptor = m->descriptor;
+
+       /* find the entry in the AVL-tree */
 
        nmn = avl_find(tree_native_methods, &tmpnmn);
 
        if (nmn == NULL)
                return NULL;
 
-       return nmn->method;
+       return nmn->function;
 }
 
 
@@ -500,11 +517,17 @@ static functionptr native_method_find(utf *name)
 
 *******************************************************************************/
 
-#if !defined(WITH_STATIC_CLASSPATH)
+#if defined(ENABLE_LTDL)
 lt_dlhandle native_library_open(utf *filename)
 {
        lt_dlhandle handle;
 
+       if (opt_verbosejni) {
+               printf("[Loading native library ");
+               utf_display_printable_ascii(filename);
+               printf(" ... ");
+       }
+
        /* try to open the library */
 
        handle = lt_dlopen(filename->text);
@@ -531,9 +554,8 @@ lt_dlhandle native_library_open(utf *filename)
 
 *******************************************************************************/
 
-#if !defined(WITH_STATIC_CLASSPATH)
-void native_library_add(utf *filename, java_objectheader *loader,
-                                               lt_dlhandle handle)
+#if defined(ENABLE_LTDL)
+void native_library_add(utf *filename, classloader *loader, lt_dlhandle handle)
 {
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne; /* library name                       */
@@ -605,7 +627,7 @@ void native_library_add(utf *filename, java_objectheader *loader,
 
        LOCK_MONITOR_EXIT(hashtable_library->header);
 }
-#endif /* !defined(WITH_STATIC_CLASSPATH) */
+#endif
 
 
 /* native_library_find *********************************************************
@@ -614,9 +636,9 @@ void native_library_add(utf *filename, java_objectheader *loader,
 
 *******************************************************************************/
 
-#if !defined(WITH_STATIC_CLASSPATH)
+#if defined(ENABLE_LTDL)
 hashtable_library_name_entry *native_library_find(utf *filename,
-                                                                                                 java_objectheader *loader)
+                                                                                                 classloader *loader)
 {
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne; /* library name                       */
@@ -710,9 +732,7 @@ functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
 
        /* no function was found, throw exception */
 
-       *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
-                                                                        mname);
+       exceptions_throw_unsatisfiedlinkerror(mname);
 
        return NULL;
 }
@@ -727,13 +747,22 @@ functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
 
 functionptr native_resolve_function(methodinfo *m)
 {
+       classloader                    *cl;
        utf                            *name;
        utf                            *newname;
        functionptr                     f;
+#if defined(ENABLE_LTDL)
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne;
        u4                              key;    /* hashkey                        */
        u4                              slot;   /* slot in hashtable              */
+#endif
+#if defined(WITH_CLASSPATH_SUN)
+       methodinfo                     *method_findNative;
+       java_handle_t                  *s;
+#endif
+
+       cl = m->class->classloader;
 
        /* verbose output */
 
@@ -758,9 +787,10 @@ functionptr native_resolve_function(methodinfo *m)
 
        f = NULL;
 
+#if defined(ENABLE_LTDL)
        /* normally addresses are aligned to 4, 8 or 16 bytes */
 
-       key  = ((u4) (ptrint) m->class->classloader) >> 4;    /* align to 16-byte */
+       key  = ((u4) (ptrint) cl) >> 4;                       /* align to 16-byte */
        slot = key & (hashtable_library->size - 1);
        le   = hashtable_library->ptr[slot];
 
@@ -783,18 +813,50 @@ functionptr native_resolve_function(methodinfo *m)
                le = le->hashlink;
        }
 
+# if defined(WITH_CLASSPATH_SUN)
+       if (f == NULL) {
+               /* We can resolve the function directly from
+                  java.lang.ClassLoader as it's a static function. */
+               /* XXX should be done in native_init */
+
+               method_findNative =
+                       class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                        utf_findNative,
+                                                                        utf_java_lang_ClassLoader_java_lang_String__J,
+                                                                        class_java_lang_ClassLoader,
+                                                                        true);
+
+               if (method_findNative == NULL)
+                       return NULL;
+
+               /* try the normal name */
+
+               s = javastring_new(name);
+
+               f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+                                                                                                                NULL, cl, s);
+
+               /* if not found, try the mangled name */
+
+               if (f == NULL) {
+                       s = javastring_new(newname);
+
+                       f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+                                                                                                                        NULL, cl, s);
+               }
+       }
+# endif
+
        if (f != NULL)
                if (opt_verbosejni)
                        printf("JNI ]\n");
+#endif
 
        /* If not found, try to find the native function symbol in the
           main program. */
 
        if (f == NULL) {
-               f = native_method_find(name);
-
-               if (f == NULL)
-                       f = native_method_find(newname);
+               f = native_method_find(m);
 
                if (f != NULL)
                        if (opt_verbosejni)
@@ -827,10 +889,10 @@ functionptr native_resolve_function(methodinfo *m)
                        
 *******************************************************************************/
 
-java_objectheader *native_new_and_init(classinfo *c)
+java_handle_t *native_new_and_init(classinfo *c)
 {
-       methodinfo *m;
-       java_objectheader *o;
+       methodinfo    *m;
+       java_handle_t *o;
 
        if (c == NULL)
                vm_abort("native_new_and_init: c == NULL");
@@ -860,10 +922,10 @@ java_objectheader *native_new_and_init(classinfo *c)
 }
 
 
-java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s)
+java_handle_t *native_new_and_init_string(classinfo *c, java_handle_t *s)
 {
-       methodinfo        *m;
-       java_objectheader *o;
+       methodinfo    *m;
+       java_handle_t *o;
 
        if (c == NULL)
                vm_abort("native_new_and_init_string: c == NULL");
@@ -877,11 +939,7 @@ java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s
 
        /* find initializer */
 
-       m = class_resolveclassmethod(c,
-                                                                utf_init,
-                                                                utf_java_lang_String__void,
-                                                                NULL,
-                                                                true);
+       m = class_findmethod(c, utf_init, utf_java_lang_String__void);
 
        /* initializer not found */
 
@@ -896,70 +954,6 @@ java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s
 }
 
 
-java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
-{
-       methodinfo *m;
-       java_objectheader *o;
-
-       if (c == NULL)
-               vm_abort("native_new_and_init_int: c == NULL");
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* find initializer */
-
-       m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
-
-       /* initializer not found  */
-
-       if (m == NULL)
-               return NULL;
-
-       /* call initializer */
-
-       (void) vm_call_method(m, o, i);
-
-       return o;
-}
-
-
-java_objectheader *native_new_and_init_throwable(classinfo *c, java_objectheader *t)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-
-       if (c == NULL)
-               vm_abort("native_new_and_init_throwable: c == NULL");
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* find initializer */
-
-       m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
-                                                     
-       /* initializer not found */
-
-       if (m == NULL)
-               return NULL;
-
-       /* call initializer */
-
-       (void) vm_call_method(m, o, t);
-
-       return o;
-}
-
-
 /*
  * 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