* configure.ac,
[cacao.git] / src / native / native.c
index a7c84298322565968fbbb97d4980e05f9cb4c417..5cc8cc0247df3bd18c91878190daecb2349099a0 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/native.c - table of native functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Roman Obermaisser
-            Andreas Krall
-
-   Changes: Christian Thalinger
-
-   $Id: native.c 5259 2006-08-22 12:43:00Z twisti $
+   $Id: native.c 8132 2007-06-22 11:15:47Z twisti $
 
 */
 
 #include "config.h"
 
 #include <assert.h>
+#include <ctype.h>
 
 #if !defined(WITH_STATIC_CLASSPATH)
 # include <ltdl.h>
 #endif
 
+#include <stdint.h>
+
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
-#include "native/include/java_lang_Throwable.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
+#include "native/vm/nativevm.h"
 
+#include "threads/lock-common.h"
+
+#include "toolbox/avl.h"
+#include "toolbox/hashtable.h"
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vm/resolve.h"
+
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/cacaodbg.h"
 #endif
 
 /* include table of native functions ******************************************/
 
-#include "native/include/java_lang_Cloneable.h"
-#include "native/include/java_util_Properties.h"
-#include "native/include/java_io_InputStream.h"
-#include "native/include/java_io_PrintStream.h"
-
-#include "native/include/gnu_classpath_VMStackWalker.h"
-#include "native/include/gnu_classpath_VMSystemProperties.h"
-#include "native/include/gnu_java_lang_management_VMClassLoadingMXBeanImpl.h"
-#include "native/include/gnu_java_lang_management_VMMemoryMXBeanImpl.h"
-#include "native/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_VMClass.h"
-#include "native/include/java_lang_VMClassLoader.h"
-#include "native/include/java_lang_VMObject.h"
-#include "native/include/java_lang_VMRuntime.h"
-#include "native/include/java_lang_VMString.h"
-#include "native/include/java_lang_VMSystem.h"
-#include "native/include/java_lang_VMThread.h"
-#include "native/include/java_lang_VMThrowable.h"
-#include "native/include/java_lang_management_VMManagementFactory.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_lang_reflect_VMProxy.h"
-#include "native/include/java_security_VMAccessController.h"
-
-#if defined(ENABLE_JVMTI)
-#include "native/include/gnu_classpath_jdwp_event_EventRequest.h"
-#include "native/include/java_nio_ByteBuffer.h"
-#include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
-#include "native/include/gnu_classpath_jdwp_VMFrame.h"
-#include "native/include/gnu_classpath_jdwp_VMMethod.h"
-#endif
-
 #if defined(WITH_STATIC_CLASSPATH)
-
-/* these are required to prevent compiler warnings */
-
-#include "native/include/java_net_DatagramPacket.h"
-#include "native/include/java_net_InetAddress.h"
-#include "native/include/java_net_SocketImpl.h"
-
-#include "native/include/gnu_java_net_PlainDatagramSocketImpl.h"
-#include "native/include/gnu_java_net_PlainSocketImpl.h"
-#include "native/include/gnu_java_nio_PipeImpl.h"
-#include "native/include/gnu_java_nio_channels_FileChannelImpl.h"
-#include "native/include/gnu_java_nio_charset_iconv_IconvEncoder.h"
-#include "native/include/gnu_java_nio_charset_iconv_IconvDecoder.h"
-#include "native/include/java_lang_VMProcess.h"
-#include "native/include/java_nio_MappedByteBufferImpl.h"
-#include "native/include/java_nio_channels_spi_SelectorProvider.h"
-
-/* now include the native table */
-
-#include "native/nativetable.inc"
-
-#elif !defined(ENABLE_LIBJVM)
-
-/* dummynativetable ************************************************************
-
-   Ensure that symbols for functions implemented within CACAO are used
-   and exported to dlopen.
-
-   ATTENTION: Don't make this table static!!!  Otherwise the compiler
-   may optimize it away!
-
-*******************************************************************************/
-
-functionptr dummynativetable[] = {
-       (functionptr) Java_gnu_classpath_VMStackWalker_getClassContext,
-       (functionptr) Java_gnu_classpath_VMStackWalker_getCallingClass,
-       (functionptr) Java_gnu_classpath_VMStackWalker_getCallingClassLoader,
-       (functionptr) Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader,
-
-       (functionptr) Java_gnu_classpath_VMSystemProperties_preInit,
-
-       (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount,
-       (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount,
-       (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose,
-       (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose,
-
-       (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage,
-       (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage,
-       (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount,
-       (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose,
-       (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose,
-
-       (functionptr) Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments,
-       (functionptr) Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime,
-
-       (functionptr) Java_java_lang_VMClass_isInstance,
-       (functionptr) Java_java_lang_VMClass_isAssignableFrom,
-       (functionptr) Java_java_lang_VMClass_isInterface,
-       (functionptr) Java_java_lang_VMClass_isPrimitive,
-       (functionptr) Java_java_lang_VMClass_getName,
-       (functionptr) Java_java_lang_VMClass_getSuperclass,
-       (functionptr) Java_java_lang_VMClass_getInterfaces,
-       (functionptr) Java_java_lang_VMClass_getComponentType,
-       (functionptr) Java_java_lang_VMClass_getModifiers,
-       (functionptr) Java_java_lang_VMClass_getDeclaringClass,
-       (functionptr) Java_java_lang_VMClass_getDeclaredClasses,
-       (functionptr) Java_java_lang_VMClass_getDeclaredFields,
-       (functionptr) Java_java_lang_VMClass_getDeclaredMethods,
-       (functionptr) Java_java_lang_VMClass_getDeclaredConstructors,
-       (functionptr) Java_java_lang_VMClass_getClassLoader,
-       (functionptr) Java_java_lang_VMClass_forName,
-       (functionptr) Java_java_lang_VMClass_isArray,
-       (functionptr) Java_java_lang_VMClass_throwException,
-
-       (functionptr) Java_java_lang_VMClassLoader_defineClass,
-       (functionptr) Java_java_lang_VMClassLoader_resolveClass,
-       (functionptr) Java_java_lang_VMClassLoader_loadClass,
-       (functionptr) Java_java_lang_VMClassLoader_getPrimitiveClass,
-       (functionptr) Java_java_lang_VMClassLoader_nativeGetResources,
-       (functionptr) Java_java_lang_VMClassLoader_findLoadedClass,
-
-       (functionptr) Java_java_lang_VMObject_getClass,
-       (functionptr) Java_java_lang_VMObject_clone,
-       (functionptr) Java_java_lang_VMObject_notify,
-       (functionptr) Java_java_lang_VMObject_notifyAll,
-       (functionptr) Java_java_lang_VMObject_wait,
-
-       (functionptr) Java_java_lang_VMRuntime_availableProcessors,
-       (functionptr) Java_java_lang_VMRuntime_freeMemory,
-       (functionptr) Java_java_lang_VMRuntime_totalMemory,
-       (functionptr) Java_java_lang_VMRuntime_maxMemory,
-       (functionptr) Java_java_lang_VMRuntime_gc,
-       (functionptr) Java_java_lang_VMRuntime_runFinalization,
-       (functionptr) Java_java_lang_VMRuntime_runFinalizationForExit,
-       (functionptr) Java_java_lang_VMRuntime_traceInstructions,
-       (functionptr) Java_java_lang_VMRuntime_traceMethodCalls,
-       (functionptr) Java_java_lang_VMRuntime_runFinalizersOnExit,
-       (functionptr) Java_java_lang_VMRuntime_exit,
-       (functionptr) Java_java_lang_VMRuntime_nativeLoad,
-       (functionptr) Java_java_lang_VMRuntime_mapLibraryName,
-
-       (functionptr) Java_java_lang_VMString_intern,
-
-       (functionptr) Java_java_lang_VMSystem_arraycopy,
-       (functionptr) Java_java_lang_VMSystem_identityHashCode,
-
-       (functionptr) Java_java_lang_VMThread_start,
-       (functionptr) Java_java_lang_VMThread_interrupt,
-       (functionptr) Java_java_lang_VMThread_isInterrupted,
-       (functionptr) Java_java_lang_VMThread_suspend,
-       (functionptr) Java_java_lang_VMThread_resume,
-       (functionptr) Java_java_lang_VMThread_nativeSetPriority,
-       (functionptr) Java_java_lang_VMThread_nativeStop,
-       (functionptr) Java_java_lang_VMThread_currentThread,
-       (functionptr) Java_java_lang_VMThread_yield,
-       (functionptr) Java_java_lang_VMThread_interrupted,
-       (functionptr) Java_java_lang_VMThread_holdsLock,
-
-       (functionptr) Java_java_lang_VMThrowable_fillInStackTrace,
-       (functionptr) Java_java_lang_VMThrowable_getStackTrace,
-
-       (functionptr) Java_java_lang_management_VMManagementFactory_getMemoryPoolNames,
-       (functionptr) Java_java_lang_management_VMManagementFactory_getMemoryManagerNames,
-       (functionptr) Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames,
-
-       (functionptr) Java_java_lang_reflect_Constructor_getModifiersInternal,
-       (functionptr) Java_java_lang_reflect_Constructor_constructNative,
-
-       (functionptr) Java_java_lang_reflect_Field_getModifiersInternal,
-       (functionptr) Java_java_lang_reflect_Field_getType,
-       (functionptr) Java_java_lang_reflect_Field_get,
-       (functionptr) Java_java_lang_reflect_Field_getBoolean,
-       (functionptr) Java_java_lang_reflect_Field_getByte,
-       (functionptr) Java_java_lang_reflect_Field_getChar,
-       (functionptr) Java_java_lang_reflect_Field_getShort,
-       (functionptr) Java_java_lang_reflect_Field_getInt,
-       (functionptr) Java_java_lang_reflect_Field_getLong,
-       (functionptr) Java_java_lang_reflect_Field_getFloat,
-       (functionptr) Java_java_lang_reflect_Field_getDouble,
-       (functionptr) Java_java_lang_reflect_Field_set,
-       (functionptr) Java_java_lang_reflect_Field_setBoolean,
-       (functionptr) Java_java_lang_reflect_Field_setByte,
-       (functionptr) Java_java_lang_reflect_Field_setChar,
-       (functionptr) Java_java_lang_reflect_Field_setShort,
-       (functionptr) Java_java_lang_reflect_Field_setInt,
-       (functionptr) Java_java_lang_reflect_Field_setLong,
-       (functionptr) Java_java_lang_reflect_Field_setFloat,
-       (functionptr) Java_java_lang_reflect_Field_setDouble,
-
-       (functionptr) Java_java_lang_reflect_Method_getModifiersInternal,
-       (functionptr) Java_java_lang_reflect_Method_getReturnType,
-       (functionptr) Java_java_lang_reflect_Method_getParameterTypes,
-       (functionptr) Java_java_lang_reflect_Method_getExceptionTypes,
-       (functionptr) Java_java_lang_reflect_Method_invokeNative,
-
-       (functionptr) Java_java_lang_reflect_VMProxy_getProxyClass,
-       (functionptr) Java_java_lang_reflect_VMProxy_getProxyData,
-       (functionptr) Java_java_lang_reflect_VMProxy_generateProxyClass,
-
-       (functionptr) Java_java_security_VMAccessController_getStack,
-
-#if defined(ENABLE_JVMTI)
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrame,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents,
-       (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses,
-       (functionptr) Java_gnu_classpath_jdwp_VMFrame_setValue,
-       (functionptr) Java_gnu_classpath_jdwp_VMFrame_getValue,
-       (functionptr) Java_gnu_classpath_jdwp_VMMethod_getName,
-       (functionptr) Java_gnu_classpath_jdwp_VMMethod_getSignature,
-       (functionptr) Java_gnu_classpath_jdwp_VMMethod_getModifiers,
-       (functionptr) Java_gnu_classpath_jdwp_VMMethod_getLineTable,
-       (functionptr) Java_gnu_classpath_jdwp_VMMethod_getVariableTable
+# include "native/nativetable.inc"
 #endif
 
-};
-
-#endif /* defined(ENABLE_LIBJVM) */
-
 
 /* tables for methods *********************************************************/
 
@@ -321,15 +93,18 @@ static bool nativecompdone = false;
 
 /* global variables ***********************************************************/
 
-#if !defined(WITH_STATIC_CLASSPATH)
+static avl_tree_t *tree_native_methods;
 static hashtable *hashtable_library;
-static lt_dlhandle mainhandle;
-#endif
 
 
-/* native_loadclasses **********************************************************
+/* prototypes *****************************************************************/
+
+static s4 native_tree_native_methods_comparator(const void *treenode, const void *node);
+
 
-   Load classes required for native methods.
+/* native_init *****************************************************************
+
+   Initializes the native subsystem.
 
 *******************************************************************************/
 
@@ -338,17 +113,8 @@ bool native_init(void)
 #if !defined(WITH_STATIC_CLASSPATH)
        /* initialize libltdl */
 
-       if (lt_dlinit()) {
-               /* XXX how can we throw an exception here? */
-               log_text(lt_dlerror());
-
-               return false;
-       }
-
-       /* get the handle for the main program */
-
-       if (!(mainhandle = lt_dlopen(NULL)))
-               return false;
+       if (lt_dlinit())
+               vm_abort("native_init: lt_dlinit failed: %s\n", lt_dlerror());
 
        /* initialize library hashtable, 10 entries should be enough */
 
@@ -357,205 +123,58 @@ bool native_init(void)
        hashtable_create(hashtable_library, 10);
 #endif
 
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* native_hashtable_library_add ************************************************
-
-   Adds an entry to the native library hashtable.
-
-*******************************************************************************/
-
-#if !defined(WITH_STATIC_CLASSPATH)
-void native_hashtable_library_add(utf *filename, java_objectheader *loader,
-                                                                 lt_dlhandle handle)
-{
-       hashtable_library_loader_entry *le;
-       hashtable_library_name_entry   *ne; /* library name                       */
-       u4   key;                           /* hashkey                            */
-       u4   slot;                          /* slot in hashtable                  */
-
-       LOCK_MONITOR_ENTER(hashtable_library->header);
-
-       /* normally addresses are aligned to 4, 8 or 16 bytes */
-
-       key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
-       slot = key & (hashtable_library->size - 1);
-       le   = hashtable_library->ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (le) {
-               if (le->loader == loader)
-                       break;
-
-               le = le->hashlink;                  /* next element in external chain */
-       }
-
-       /* no loader found? create a new entry */
-
-       if (le == NULL) {
-               le = NEW(hashtable_library_loader_entry);
-
-               le->loader   = loader;
-               le->namelink = NULL;
-
-               /* insert entry into hashtable */
-
-               le->hashlink =
-                       (hashtable_library_loader_entry *) hashtable_library->ptr[slot];
-               hashtable_library->ptr[slot] = le;
-
-               /* update number of hashtable-entries */
-
-               hashtable_library->entries++;
-       }
-
-
-       /* search for library name */
-
-       ne = le->namelink;
-
-       while (ne) {
-               if (ne->name == filename) {
-                       LOCK_MONITOR_EXIT(hashtable_library->header);
-
-                       return;
-               }
-
-               ne = ne->hashlink;                  /* next element in external chain */
-       }
-
-       /* not found? add the library name to the classloader */
-
-       ne = NEW(hashtable_library_name_entry);
-
-       ne->name   = filename;
-       ne->handle = handle;
+       /* initialize the native methods table */
 
-       /* insert entry into external chain */
+       tree_native_methods = avl_create(&native_tree_native_methods_comparator);
 
-       ne->hashlink = le->namelink;
-       le->namelink = ne;
+       /* everything's ok */
 
-       LOCK_MONITOR_EXIT(hashtable_library->header);
+       return true;
 }
-#endif /* !defined(WITH_STATIC_CLASSPATH) */
-
-
-/* native_hashtable_library_find ***********************************************
-
-   Find an entry in the native library hashtable.
-
-*******************************************************************************/
-
-#if !defined(WITH_STATIC_CLASSPATH)
-hashtable_library_name_entry *native_hashtable_library_find(utf *filename,
-                                                                                                                       java_objectheader *loader)
-{
-       hashtable_library_loader_entry *le;
-       hashtable_library_name_entry   *ne; /* library name                       */
-       u4   key;                           /* hashkey                            */
-       u4   slot;                          /* slot in hashtable                  */
-
-       /* normally addresses are aligned to 4, 8 or 16 bytes */
-
-       key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
-       slot = key & (hashtable_library->size - 1);
-       le   = hashtable_library->ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (le) {
-               if (le->loader == loader)
-                       break;
-
-               le = le->hashlink;                  /* next element in external chain */
-       }
-
-       /* no loader found? return NULL */
-
-       if (!le)
-               return NULL;
-
-       /* search for library name */
-
-       ne = le->namelink;
-
-       while (ne) {
-               if (ne->name == filename)
-                       return ne;
-
-               ne = ne->hashlink;                  /* next element in external chain */
-       }
-
-       /* return entry, if no entry was found, ne is NULL */
 
-       return ne;
-}
-#endif /* !defined(WITH_STATIC_CLASSPATH) */
 
+/* native_tree_native_methods_comparator ***************************************
 
-/* native_findfunction *********************************************************
+   Comparison function for AVL tree of native methods.
 
-   Looks up a method (must have the same class name, method name,
-   descriptor and 'static'ness) and returns a function pointer to it.
-   Returns: function pointer or NULL (if there is no such method)
+   IN:
+       treenode....node in the tree
+          node........node to compare with tree-node
 
-   Remark: For faster operation, the names/descriptors are converted
-   from C strings to Unicode the first time this function is called.
+   RETURN VALUE:
+       -1, 0, +1
 
 *******************************************************************************/
 
-#if defined(WITH_STATIC_CLASSPATH)
-functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
-                                                               bool isstatic)
+static s4 native_tree_native_methods_comparator(const void *treenode, const void *node)
 {
-       /* entry of table for fast string comparison */
-       struct nativecompref *n;
-       s4 i;
-
-       isstatic = isstatic ? true : false;
-       
-       if (!nativecompdone) {
-               for (i = 0; i < NATIVETABLESIZE; i++) {
-                       nativecomptable[i].classname  = 
-                               utf_new_char(nativetable[i].classname);
-
-                       nativecomptable[i].methodname = 
-                               utf_new_char(nativetable[i].methodname);
-
-                       nativecomptable[i].descriptor =
-                               utf_new_char(nativetable[i].descriptor);
+       const native_methods_node_t *treenmn;
+       const native_methods_node_t *nmn;
 
-                       nativecomptable[i].isstatic   = nativetable[i].isstatic;
-                       nativecomptable[i].func       = nativetable[i].func;
-               }
+       treenmn = treenode;
+       nmn     = node;
 
-               nativecompdone = true;
-       }
+       /* these are for walking the tree */
 
-       for (i = 0; i < NATIVETABLESIZE; i++) {
-               n = &(nativecomptable[i]);
+       if (treenmn->classname < nmn->classname)
+               return -1;
+       else if (treenmn->classname > nmn->classname)
+               return 1;
 
-               if (cname == n->classname && mname == n->methodname &&
-                   desc == n->descriptor && isstatic == n->isstatic)
-                       return n->func;
-       }
+       if (treenmn->name < nmn->name)
+               return -1;
+       else if (treenmn->name > nmn->name)
+               return 1;
 
-               
-       /* no function was found, throw exception */
+       if (treenmn->descriptor < nmn->descriptor)
+               return -1;
+       else if (treenmn->descriptor > nmn->descriptor)
+               return 1;
 
-       *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
-                                                                        mname);
+       /* all pointers are equal, we have found the entry */
 
-       return NULL;
+       return 0;
 }
-#endif /* defined(WITH_STATIC_CLASSPATH) */
 
 
 /* native_make_overloaded_function *********************************************
@@ -565,16 +184,22 @@ functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
 *******************************************************************************/
 
 #if !defined(WITH_STATIC_CLASSPATH)
-static char *native_make_overloaded_function(char *name, utf *desc)
+static utf *native_make_overloaded_function(utf *name, utf *descriptor)
 {
        char *newname;
        s4    namelen;
        char *utf_ptr;
        u2    c;
        s4    i;
+       s4    dumpsize;
+       utf  *u;
+
+       /* mark memory */
+
+       dumpsize = dump_size();
 
-       utf_ptr = desc->text;
-       namelen = strlen(name) + strlen("__") + strlen("0");
+       utf_ptr = descriptor->text;
+       namelen = strlen(name->text) + strlen("__") + strlen("0");
 
        /* calculate additional length */
 
@@ -606,15 +231,14 @@ static char *native_make_overloaded_function(char *name, utf *desc)
                }
        }
 
-
        /* reallocate memory */
 
-       i = strlen(name);
+       i = strlen(name->text);
 
        newname = DMNEW(char, namelen);
-       MCOPY(newname, name, char, i);
+       MCOPY(newname, name->text, char, i);
 
-       utf_ptr = desc->text;
+       utf_ptr = descriptor->text;
 
        newname[i++] = '_';
        newname[i++] = '_';
@@ -658,431 +282,671 @@ static char *native_make_overloaded_function(char *name, utf *desc)
 
        newname[i] = '\0';
 
-       return newname;
+       /* make a utf-string */
+
+       u = utf_new_char(newname);
+
+       /* release memory */
+
+       dump_release(dumpsize);
+
+       return u;
 }
 
 
-/* native_resolve_function *****************************************************
+/* native_insert_char **********************************************************
 
-   Resolves a native function, maybe from a dynamic library.
+   Inserts the passed UTF character into the native method name.  If
+   necessary it is escaped properly.
 
 *******************************************************************************/
 
-functionptr native_resolve_function(methodinfo *m)
+static s4 native_insert_char(char *name, u4 pos, u2 c)
 {
-       lt_ptr                     sym;
-       char                      *name;
-       char                      *newname;
-       s4                         namelen;
-       char                      *utf_ptr;
-       char                      *utf_endptr;
-       s4                         dumpsize;
-       hashtable_library_loader_entry *le;
-       hashtable_library_name_entry   *ne;
-       u4                         key;     /* hashkey                            */
-       u4                         slot;    /* slot in hashtable                  */
-       u4                         i;
-
+       s4 val;
+       s4 i;
 
-       /* verbose output */
+       switch (c) {
+       case '/':
+       case '.':
+               /* replace '/' or '.' with '_' */
+               name[pos] = '_';
+               break;
 
-       if (opt_verbosejni) {
-               printf("[Dynamic-linking native method ");
-               utf_display_printable_ascii_classname(m->class->name);
-               printf(".");
-               utf_display_printable_ascii(m->name);
-               printf(" ... ");
+       case '_':
+               /* escape sequence for '_' is '_1' */
+               name[pos]   = '_';
+               name[++pos] = '1';
+               break;
+
+       case ';':
+               /* escape sequence for ';' is '_2' */
+               name[pos]   = '_';
+               name[++pos] = '2';
+               break;
+
+       case '[':
+               /* escape sequence for '[' is '_1' */
+               name[pos]   = '_';
+               name[++pos] = '3';
+               break;
+
+       default:
+               if (isalnum(c))
+                       name[pos] = c;
+               else {
+                       /* unicode character */
+                       name[pos]   = '_';
+                       name[++pos] = '0';
+
+                       for (i = 0; i < 4; ++i) {
+                               val = c & 0x0f;
+                               name[pos + 4 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
+                               c >>= 4;
+                       }
+
+                       pos += 4;
+               }
+               break;
        }
-               
-       /* calculate length of native function name */
 
-       namelen = strlen("Java_") + utf_get_number_of_u2s(m->class->name) + strlen("_") +
-               utf_get_number_of_u2s(m->name) + strlen("0");
+       /* return the new buffer index */
 
-       /* check for underscores in class name */
+       return pos;
+}
 
-       utf_ptr = m->class->name->text;
-       utf_endptr = UTF_END(m->class->name);
 
-       while (utf_ptr < utf_endptr)
-               if (utf_nextu2(&utf_ptr) == '_')
-                       namelen++;
+/* native_method_symbol ********************************************************
 
-       /* check for underscores in method name */
+   Generate a method-symbol string out of the class name and the
+   method name.
 
-       utf_ptr = m->name->text;
-       utf_endptr = UTF_END(m->name);
+*******************************************************************************/
 
-       while (utf_ptr < utf_endptr)
-               if (utf_nextu2(&utf_ptr) == '_')
-                       namelen++;
+static utf *native_method_symbol(utf *classname, utf *methodname)
+{
+       char *name;
+       s4    namelen;
+       char *utf_ptr;
+       char *utf_endptr;
+       u2    c;
+       u4    pos;
+       s4    dumpsize;
+       utf  *u;
 
-       /* allocate memory */
+       /* mark memory */
 
        dumpsize = dump_size();
 
-       name = DMNEW(char, namelen);
+       /* Calculate length of native function name.  We multiply the
+          class and method name length by 6 as this is the maxium
+          escape-sequence that can be generated (unicode). */
+
+       namelen =
+               strlen("Java_") +
+               utf_get_number_of_u2s(classname) * 6 +
+               strlen("_") +
+               utf_get_number_of_u2s(methodname) * 6 +
+               strlen("0");
+
+       /* allocate memory */
 
+       name = DMNEW(char, namelen);
 
        /* generate name of native functions */
 
        strcpy(name, "Java_");
-       i = strlen("Java_");
+       pos = strlen("Java_");
 
-       utf_ptr = m->class->name->text;
-       utf_endptr = UTF_END(m->class->name);
+       utf_ptr    = classname->text;
+       utf_endptr = UTF_END(classname);
 
-       for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
-               name[i] = *utf_ptr;
+       for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
+               c   = *utf_ptr;
+               pos = native_insert_char(name, pos, c);
+       }
 
-               /* escape sequence for '_' is '_1' */
+       /* seperator between class and method */
 
-               if (name[i] == '_')
-                       name[++i] = '1';
+       name[pos++] = '_';
 
-               /* replace '/' with '_' */
+       utf_ptr    = methodname->text;
+       utf_endptr = UTF_END(methodname);
 
-               if (name[i] == '/')
-                       name[i] = '_';
+       for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
+               c   = *utf_ptr;
+               pos = native_insert_char(name, pos, c);
        }
 
-       /* seperator between class and method */
+       /* close string */
 
-       name[i++] = '_';
+       name[pos] = '\0';
 
-       utf_ptr = m->name->text;
-       utf_endptr = UTF_END(m->name);
+       /* check for an buffer overflow */
 
-       for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
-               name[i] = *utf_ptr;
+       assert(pos <= namelen);
 
-               /* escape sequence for '_' is '_1' */
+       /* make a utf-string */
 
-               if (name[i] == '_')
-                       name[++i] = '1';
-       }
+       u = utf_new_char(name);
 
-       /* close string */
+       /* release memory */
 
-       name[i] = '\0';
+       dump_release(dumpsize);
 
+       return u;
+}
 
-       /* generate overloaded function (having the types in it's name)           */
 
-       newname = native_make_overloaded_function(name, m->descriptor);
+/* native_method_register ******************************************************
 
-       /* check the library hash entries of the classloader of the
-          methods's class  */
+   Register a native method in the native method table.
 
-       sym = NULL;
+*******************************************************************************/
 
-       /* normally addresses are aligned to 4, 8 or 16 bytes */
+void native_method_register(utf *classname, const JNINativeMethod *methods,
+                                                       int32_t count)
+{
+       native_methods_node_t *nmn;
+       utf                   *name;
+       utf                   *descriptor;
+       int32_t                i;
+
+       /* insert all methods passed */
+
+       for (i = 0; i < count; i++) {
+               if (opt_verbosejni) {
+                       printf("[Registering JNI native method ");
+                       utf_display_printable_ascii_classname(classname);
+                       printf(".%s]\n", methods[i].name);
+               }
 
-       key  = ((u4) (ptrint) m->class->classloader) >> 4;    /* align to 16-byte */
-       slot = key & (hashtable_library->size - 1);
-       le   = hashtable_library->ptr[slot];
+               /* generate the utf8 names */
 
-       /* iterate through loaders in this hash slot */
+               name       = utf_new_char(methods[i].name);
+               descriptor = utf_new_char(methods[i].signature);
 
-       while ((le != NULL) && (sym == NULL)) {
-               /* iterate through names in this loader */
+               /* allocate a new tree node */
 
-               ne = le->namelink;
-                       
-               while ((ne != NULL) && (sym == NULL)) {
-                       sym = lt_dlsym(ne->handle, name);
+               nmn = NEW(native_methods_node_t);
 
-                       if (sym == NULL)
-                               sym = lt_dlsym(ne->handle, newname);
+               nmn->classname  = classname;
+               nmn->name       = name;
+               nmn->descriptor = descriptor;
+               nmn->function   = (functionptr) (ptrint) methods[i].fnPtr;
 
-                       ne = ne->hashlink;
-               }
+               /* insert the method into the tree */
 
-               le = le->hashlink;
+               avl_insert(tree_native_methods, nmn);
        }
+}
 
-       if (sym != NULL)
-               if (opt_verbosejni)
-                       printf("JNI ]\n");
 
+/* native_method_find **********************************************************
 
-       /* If not found, try to find the native function symbol in the
-          main program. */
+   Find a native method in the native method table.
 
-       if (sym == NULL) {
-               sym = lt_dlsym(mainhandle, name);
+*******************************************************************************/
 
-               if (sym == NULL)
-                       sym = lt_dlsym(mainhandle, newname);
+static functionptr native_method_find(methodinfo *m)
+{
+       native_methods_node_t  tmpnmn;
+       native_methods_node_t *nmn;
 
-               if (sym != NULL)
-                       if (opt_verbosejni)
-                               printf("internal ]\n");
-       }
+       /* fill the temporary structure used for searching the tree */
 
+       tmpnmn.classname  = m->class->name;
+       tmpnmn.name       = m->name;
+       tmpnmn.descriptor = m->descriptor;
 
-#if defined(ENABLE_JVMTI)
-       /* fire Native Method Bind event */
-       if (jvmti) jvmti_NativeMethodBind(m, sym, &sym);
-#endif
+       /* find the entry in the AVL-tree */
 
-       /* no symbol found? throw exception */
+       nmn = avl_find(tree_native_methods, &tmpnmn);
 
-       if (sym == NULL) {
-               if (opt_verbosejni)
-                       printf("failed ]\n");
+       if (nmn == NULL)
+               return NULL;
 
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
-                                                                        m->name);
+       return nmn->function;
+}
+
+
+/* native_library_open *********************************************************
+
+   Open a native library with the given utf8 name.
+
+*******************************************************************************/
+
+#if !defined(WITH_STATIC_CLASSPATH)
+lt_dlhandle native_library_open(utf *filename)
+{
+       lt_dlhandle handle;
+
+       if (opt_verbosejni) {
+               printf("[Loading native library ");
+               utf_display_printable_ascii(filename);
+               printf(" ... ");
        }
 
-       /* release memory */
+       /* try to open the library */
 
-       dump_release(dumpsize);
+       handle = lt_dlopen(filename->text);
+
+       if (handle == NULL) {
+               if (opt_verbose) {
+                       log_start();
+                       log_print("native_library_load: lt_dlopen failed: ");
+                       log_print(lt_dlerror());
+                       log_finish();
+               }
+
+               return NULL;
+       }
 
-       return (functionptr) (ptrint) sym;
+       return handle;
 }
-#endif /* !defined(WITH_STATIC_CLASSPATH) */
+#endif
 
 
-/* native_new_and_init *********************************************************
+/* native_library_add **********************************************************
+
+   Adds an entry to the native library hashtable.
 
-   Creates a new object on the heap and calls the initializer.
-   Returns the object pointer or NULL if memory is exhausted.
-                       
 *******************************************************************************/
 
-java_objectheader *native_new_and_init(classinfo *c)
+#if !defined(WITH_STATIC_CLASSPATH)
+void native_library_add(utf *filename, java_objectheader *loader,
+                                               lt_dlhandle handle)
 {
-       methodinfo *m;
-       java_objectheader *o;
+       hashtable_library_loader_entry *le;
+       hashtable_library_name_entry   *ne; /* library name                       */
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
 
-       if (!c)
-               return *exceptionptr;
+       LOCK_MONITOR_ENTER(hashtable_library->header);
 
-       /* create object */
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
 
-       o = builtin_new(c);
-       
-       if (!o)
-               return NULL;
+       key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
+       slot = key & (hashtable_library->size - 1);
+       le   = hashtable_library->ptr[slot];
 
-       /* try to find the initializer */
+       /* search external hash chain for the entry */
 
-       m = class_findmethod(c, utf_init, utf_void__void);
-                                                     
-       /* ATTENTION: returning the object here is ok, since the class may
-       not have an initializer */
+       while (le) {
+               if (le->loader == loader)
+                       break;
 
-       if (!m)
-               return o;
+               le = le->hashlink;                  /* next element in external chain */
+       }
 
-       /* call initializer */
+       /* no loader found? create a new entry */
 
-       (void) vm_call_method(m, o);
+       if (le == NULL) {
+               le = NEW(hashtable_library_loader_entry);
 
-       return o;
-}
+               le->loader   = loader;
+               le->namelink = NULL;
 
+               /* insert entry into hashtable */
 
-java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
-{
-       methodinfo *m;
-       java_objectheader *o;
+               le->hashlink =
+                       (hashtable_library_loader_entry *) hashtable_library->ptr[slot];
+               hashtable_library->ptr[slot] = le;
 
-       if (!c)
-               return *exceptionptr;
+               /* update number of hashtable-entries */
 
-       /* create object */
+               hashtable_library->entries++;
+       }
 
-       o = builtin_new(c);
 
-       if (!o)
-               return NULL;
+       /* search for library name */
 
-       /* find initializer */
+       ne = le->namelink;
 
-       m = class_resolveclassmethod(c,
-                                                                utf_init,
-                                                                utf_java_lang_String__void,
-                                                                NULL,
-                                                                true);
+       while (ne) {
+               if (ne->name == filename) {
+                       LOCK_MONITOR_EXIT(hashtable_library->header);
 
-       /* initializer not found */
+                       return;
+               }
 
-       if (!m)
-               return NULL;
+               ne = ne->hashlink;                  /* next element in external chain */
+       }
 
-       /* call initializer */
+       /* not found? add the library name to the classloader */
 
-       (void) vm_call_method(m, o, s);
+       ne = NEW(hashtable_library_name_entry);
 
-       return o;
+       ne->name   = filename;
+       ne->handle = handle;
+
+       /* insert entry into external chain */
+
+       ne->hashlink = le->namelink;
+       le->namelink = ne;
+
+       LOCK_MONITOR_EXIT(hashtable_library->header);
 }
+#endif /* !defined(WITH_STATIC_CLASSPATH) */
+
 
+/* native_library_find *********************************************************
 
-java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
+   Find an entry in the native library hashtable.
+
+*******************************************************************************/
+
+#if !defined(WITH_STATIC_CLASSPATH)
+hashtable_library_name_entry *native_library_find(utf *filename,
+                                                                                                 java_objectheader *loader)
 {
-       methodinfo *m;
-       java_objectheader *o;
+       hashtable_library_loader_entry *le;
+       hashtable_library_name_entry   *ne; /* library name                       */
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
 
-       if (!c)
-               return *exceptionptr;
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
 
-       /* create object */
+       key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
+       slot = key & (hashtable_library->size - 1);
+       le   = hashtable_library->ptr[slot];
 
-       o = builtin_new(c);
-       
-       if (!o)
-               return NULL;
+       /* search external hash chain for the entry */
 
-       /* find initializer */
+       while (le) {
+               if (le->loader == loader)
+                       break;
 
-       m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
+               le = le->hashlink;                  /* next element in external chain */
+       }
 
-       /* initializer not found  */
+       /* no loader found? return NULL */
 
-       if (!m)
+       if (le == NULL)
                return NULL;
 
-       /* call initializer */
+       /* search for library name */
 
-       (void) vm_call_method(m, o, i);
+       ne = le->namelink;
 
-       return o;
+       while (ne) {
+               if (ne->name == filename)
+                       return ne;
+
+               ne = ne->hashlink;                  /* next element in external chain */
+       }
+
+       /* return entry, if no entry was found, ne is NULL */
+
+       return ne;
 }
+#endif /* !defined(WITH_STATIC_CLASSPATH) */
 
 
-java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
-{
-       methodinfo *m;
-       java_objectheader *o;
+/* native_findfunction *********************************************************
 
-       if (!c)
-               return *exceptionptr;
+   Looks up a method (must have the same class name, method name,
+   descriptor and 'static'ness) and returns a function pointer to it.
+   Returns: function pointer or NULL (if there is no such method)
 
-       /* create object */
+   Remark: For faster operation, the names/descriptors are converted
+   from C strings to Unicode the first time this function is called.
 
-       o = builtin_new(c);
+*******************************************************************************/
+
+#if defined(WITH_STATIC_CLASSPATH)
+functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
+                                                               bool isstatic)
+{
+       /* entry of table for fast string comparison */
+       struct nativecompref *n;
+       s4 i;
+
+       isstatic = isstatic ? true : false;
        
-       if (!o)
-               return NULL;
+       if (!nativecompdone) {
+               for (i = 0; i < NATIVETABLESIZE; i++) {
+                       nativecomptable[i].classname  = 
+                               utf_new_char(nativetable[i].classname);
 
-       /* find initializer */
+                       nativecomptable[i].methodname = 
+                               utf_new_char(nativetable[i].methodname);
 
-       m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
-                                                     
-       /* initializer not found */
+                       nativecomptable[i].descriptor =
+                               utf_new_char(nativetable[i].descriptor);
 
-       if (!m)
-               return NULL;
+                       nativecomptable[i].isstatic   = nativetable[i].isstatic;
+                       nativecomptable[i].func       = nativetable[i].func;
+               }
 
-       /* call initializer */
+               nativecompdone = true;
+       }
 
-       (void) vm_call_method(m, o, t);
+       for (i = 0; i < NATIVETABLESIZE; i++) {
+               n = &(nativecomptable[i]);
 
-       return o;
+               if (cname == n->classname && mname == n->methodname &&
+                   desc == n->descriptor && isstatic == n->isstatic)
+                       return n->func;
+       }
+
+       /* no function was found, throw exception */
+
+       exceptions_throw_unsatisfiedlinkerror(mname);
+
+       return NULL;
 }
+#endif /* defined(WITH_STATIC_CLASSPATH) */
 
 
-/* native_get_parametertypes ***************************************************
+/* native_resolve_function *****************************************************
 
-   Use the descriptor of a method to generate a java/lang/Class array
-   which contains the classes of the parametertypes of the method.
+   Resolves a native function, maybe from a dynamic library.
 
 *******************************************************************************/
 
-java_objectarray *native_get_parametertypes(methodinfo *m)
+functionptr native_resolve_function(methodinfo *m)
 {
-       methoddesc       *md;
-       typedesc         *paramtypes;
-       s4                paramcount;
-    java_objectarray *oa;
-       s4                i;
+       java_objectheader              *cl;
+       utf                            *name;
+       utf                            *newname;
+       functionptr                     f;
+       hashtable_library_loader_entry *le;
+       hashtable_library_name_entry   *ne;
+       u4                              key;    /* hashkey                        */
+       u4                              slot;   /* slot in hashtable              */
+#if defined(WITH_CLASSPATH_SUN)
+       methodinfo                     *method_findNative;
+       java_objectheader              *s;
+#endif
+
+       cl = m->class->classloader;
+
+       /* verbose output */
+
+       if (opt_verbosejni) {
+               printf("[Dynamic-linking native method ");
+               utf_display_printable_ascii_classname(m->class->name);
+               printf(".");
+               utf_display_printable_ascii(m->name);
+               printf(" ... ");
+       }
+
+       /* generate method symbol string */
 
-       md = m->parseddesc;
+       name = native_method_symbol(m->class->name, m->name);
 
-       /* is the descriptor fully parsed? */
+       /* generate overloaded function (having the types in it's name)           */
+
+       newname = native_make_overloaded_function(name, m->descriptor);
 
-       if (!m->parseddesc->params)
-               if (!descriptor_params_from_paramtypes(md, m->flags))
+       /* check the library hash entries of the classloader of the
+          methods's class  */
+
+       f = NULL;
+
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
+
+       key  = ((u4) (ptrint) cl) >> 4;                       /* align to 16-byte */
+       slot = key & (hashtable_library->size - 1);
+       le   = hashtable_library->ptr[slot];
+
+       /* iterate through loaders in this hash slot */
+
+       while ((le != NULL) && (f == NULL)) {
+               /* iterate through names in this loader */
+
+               ne = le->namelink;
+                       
+               while ((ne != NULL) && (f == NULL)) {
+                       f = (functionptr) (ptrint) lt_dlsym(ne->handle, name->text);
+
+                       if (f == NULL)
+                               f = (functionptr) (ptrint) lt_dlsym(ne->handle, newname->text);
+
+                       ne = ne->hashlink;
+               }
+
+               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;
 
-       paramtypes = md->paramtypes;
-       paramcount = md->paramcount;
+               /* try the normal name */
+
+               s = javastring_new(name);
+
+               f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+                                                                                                                NULL, cl, s);
 
-       /* skip `this' pointer */
+               /* if not found, try the mangled name */
 
-       if (!(m->flags & ACC_STATIC)) {
-               paramtypes++;
-               paramcount--;
+               if (f == NULL) {
+                       s = javastring_new(newname);
+
+                       f = (functionptr) (intptr_t) vm_call_method_long(method_findNative,
+                                                                                                                        NULL, cl, s);
+               }
        }
+#endif
 
-       /* create class-array */
+       if (f != NULL)
+               if (opt_verbosejni)
+                       printf("JNI ]\n");
 
-       oa = builtin_anewarray(paramcount, class_java_lang_Class);
+       /* If not found, try to find the native function symbol in the
+          main program. */
 
-       if (!oa)
-               return NULL;
+       if (f == NULL) {
+               f = native_method_find(m);
+
+               if (f != NULL)
+                       if (opt_verbosejni)
+                               printf("internal ]\n");
+       }
 
-    /* get classes */
+#if defined(ENABLE_JVMTI)
+       /* fire Native Method Bind event */
+       if (jvmti) jvmti_NativeMethodBind(m, f, &f);
+#endif
 
-       for (i = 0; i < paramcount; i++)
-               if (!resolve_class_from_typedesc(&paramtypes[i], true, false,
-                                                                                (classinfo **) &oa->data[i]))
-                       return NULL;
+       /* no symbol found? throw exception */
 
-       return oa;
-}
+       if (f == NULL) {
+               if (opt_verbosejni)
+                       printf("failed ]\n");
+
+               exceptions_throw_unsatisfiedlinkerror(m->name);
+       }
 
+       return f;
+}
+#endif /* !defined(WITH_STATIC_CLASSPATH) */
 
-/* native_get_exceptiontypes ***************************************************
 
-   Get the exceptions which can be thrown by a method.
+/* native_new_and_init *********************************************************
 
+   Creates a new object on the heap and calls the initializer.
+   Returns the object pointer or NULL if memory is exhausted.
+                       
 *******************************************************************************/
 
-java_objectarray *native_get_exceptiontypes(methodinfo *m)
+java_objectheader *native_new_and_init(classinfo *c)
 {
-       java_objectarray *oa;
-       classinfo        *c;
-       u2                i;
+       methodinfo *m;
+       java_objectheader *o;
 
-       /* create class-array */
+       if (c == NULL)
+               vm_abort("native_new_and_init: c == NULL");
 
-       oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
+       /* create object */
 
-       if (!oa)
+       o = builtin_new(c);
+       
+       if (o == NULL)
                return NULL;
 
-       for (i = 0; i < m->thrownexceptionscount; i++) {
-               if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[i],
-                                                                                  resolveEager, true, false, &c))
-                       return NULL;
+       /* try to find the initializer */
 
-               oa->data[i] = (java_objectheader *) c;
-       }
+       m = class_findmethod(c, utf_init, utf_void__void);
+                                                     
+       /* ATTENTION: returning the object here is ok, since the class may
+       not have an initializer */
 
-       return oa;
-}
+       if (m == NULL)
+               return o;
 
+       /* call initializer */
 
-/* native_get_returntype *******************************************************
+       (void) vm_call_method(m, o);
 
-   Get the returntype class of a method.
+       return o;
+}
 
-*******************************************************************************/
 
-classinfo *native_get_returntype(methodinfo *m)
+java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s)
 {
-       classinfo *c;
+       methodinfo        *m;
+       java_objectheader *o;
+
+       if (c == NULL)
+               vm_abort("native_new_and_init_string: c == NULL");
+
+       /* create object */
+
+       o = builtin_new(c);
+
+       if (o == NULL)
+               return NULL;
+
+       /* find initializer */
+
+       m = class_findmethod(c, utf_init, utf_java_lang_String__void);
+
+       /* initializer not found */
 
-       if (!resolve_class_from_typedesc(&(m->parseddesc->returntype), true, false,
-                                                                        &c))
+       if (m == NULL)
                return NULL;
 
-       return c;
+       /* call initializer */
+
+       (void) vm_call_method(m, o, s);
+
+       return o;
 }