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"
/* global variables ***********************************************************/
static avl_tree_t *tree_native_methods;
+
+#if defined(ENABLE_LTDL)
static hashtable *hashtable_library;
+#endif
/* prototypes *****************************************************************/
bool native_init(void)
{
-#if !defined(WITH_STATIC_CLASSPATH)
+#if defined(ENABLE_LTDL)
/* initialize libltdl */
if (lt_dlinit())
tree_native_methods = avl_create(&native_tree_native_methods_comparator);
- /* register the intern native functions */
-
- nativevm_init();
-
/* everything's ok */
return true;
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;
}
*******************************************************************************/
-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 */
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 */
*******************************************************************************/
-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;
}
*******************************************************************************/
-#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);
*******************************************************************************/
-#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 */
LOCK_MONITOR_EXIT(hashtable_library->header);
}
-#endif /* !defined(WITH_STATIC_CLASSPATH) */
+#endif
/* native_library_find *********************************************************
*******************************************************************************/
-#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 */
/* no function was found, throw exception */
- *exceptionptr =
- new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
- mname);
+ exceptions_throw_unsatisfiedlinkerror(mname);
return NULL;
}
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 */
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];
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)
*******************************************************************************/
-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");
}
-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");
/* 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 */
}
-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