X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fnative.c;h=2b55c1d7edb66a153e280df302a6c758622762e3;hb=1b520e4e53aab1e84a93066ec651b21208c956c0;hp=cf03e74750793783ace1120bfbc1f2b92fe03d69;hpb=adc3e5437530d70d11ed1adadbe3c1172efb98a5;p=cacao.git diff --git a/src/native/native.c b/src/native/native.c index cf03e7475..2b55c1d7e 100644 --- a/src/native/native.c +++ b/src/native/native.c @@ -1,9 +1,9 @@ -/* native/native.c - table of native functions +/* src/native/native.c - table of native functions - Copyright (C) 1996-2005 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 + 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 This file is part of CACAO. @@ -19,133 +19,286 @@ 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at + Contact: cacao@cacaojvm.org Authors: Reinhard Grafl Roman Obermaisser Andreas Krall - The .hh files created with the header file generator are all - included here as are the C functions implementing these methods. + Changes: Christian Thalinger - $Id: native.c 1785 2004-12-21 09:55:33Z twisti $ + $Id: native.c 5200 2006-07-31 16:30:33Z twisti $ */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "config.h" -/* Include files for IO functions */ +#include -#include -#include -#include -#ifdef _OSF_SOURCE -#include +#if !defined(WITH_STATIC_CLASSPATH) +# include #endif -#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_Throwable.h" + +#if defined(ENABLE_THREADS) +# include "threads/native/lock.h" +#else +# include "threads/none/lock.h" +#endif + #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/tables.h" +#include "vm/resolve.h" +#include "vm/stringlocal.h" +#include "vm/vm.h" #include "vm/jit/asmpart.h" #include "vm/jit/jit.h" - -/* include table of native functions ******************************************/ - -/* XXX quick hack? */ -#if defined(USE_GTK) -#include "native/vm/GtkComponentPeer.c" -#include "native/vm/GtkScrollPanePeer.c" -#include "native/vm/GtkFileDialogPeer.c" +#if defined(ENABLE_JVMTI) +#include "native/jvmti/cacaodbg.h" #endif -#include "nativetable.inc" +/* include table of native functions ******************************************/ -/* for java-string to char conversion */ -#define MAXSTRINGSIZE 1000 - - -/******************** systemclasses required for native methods ***************/ - -classinfo *class_java_lang_Class; -classinfo *class_java_lang_VMClass; -classinfo *class_java_lang_System; -classinfo *class_java_lang_ClassLoader; -classinfo *class_gnu_java_lang_SystemClassLoader; -classinfo *class_java_lang_SecurityManager; -classinfo *class_java_lang_Double; -classinfo *class_java_lang_Float; -classinfo *class_java_lang_Long; -classinfo *class_java_lang_Byte; -classinfo *class_java_lang_Short; -classinfo *class_java_lang_Boolean; -classinfo *class_java_lang_Void; -classinfo *class_java_lang_Character; -classinfo *class_java_lang_Integer; - -methodinfo *method_vmclass_init; - - -/* the system classloader object */ -struct java_lang_ClassLoader *SystemClassLoader = NULL; - -/* for raising exceptions from native methods */ -#if !defined(USE_THREADS) || !defined(NATIVE_THREADS) -java_objectheader* _exceptionptr = NULL; +#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 -/************* use classinfo structure as java.lang.Class object **************/ +#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" + +#else /* defined(WITH_STATIC_CLASSPATH) */ + +/* Ensure that symbols for functions implemented within CACAO are used + and exported to dlopen. */ + +static functionptr dummynativetable[] = { + (functionptr) Java_gnu_classpath_VMStackWalker_getClassContext, + + (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 +#endif -void use_class_as_object(classinfo *c) -{ - if (!c->classvftbl) { - /* is the class loaded */ - if (!c->loaded) - if (!class_load(c)) - panic("Class could not be loaded in use_class_as_object"); - /* is the class linked */ - if (!c->linked) - if (!class_link(c)) - panic("Class could not be linked in use_class_as_object"); - - /*if (class_java_lang_Class ==0) panic("java/lang/Class not loaded in use_class_as_object"); - if (class_java_lang_Class->vftbl ==0) panic ("vftbl == 0 in use_class_as_object");*/ - c->header.vftbl = class_java_lang_Class->vftbl; - c->classvftbl = true; - /*printf("use_class_as_object: %s\n",c->name->text);*/ - } - -} +}; +#endif /* defined(WITH_STATIC_CLASSPATH) */ -/************************** tables for methods ********************************/ -#undef JOWENN_DEBUG -#undef JOWENN_DEBUG1 +/* tables for methods *********************************************************/ -#ifdef STATIC_CLASSPATH +#if defined(WITH_STATIC_CLASSPATH) #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref)) /* table for fast string comparison */ @@ -156,1362 +309,778 @@ static bool nativecompdone = false; #endif -/* XXX don't define this in a header file!!! */ - -static struct nativeCall nativeCalls[] = -{ -#include "nativecalls.inc" -}; - -#define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall)) - -struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE]; +/* global variables ***********************************************************/ -/******************************************************************************/ - -/**include "natcalls.h" **/ +#if !defined(WITH_STATIC_CLASSPATH) +static hashtable *hashtable_library; +static lt_dlhandle mainhandle; +#endif -/*********************** function: native_loadclasses ************************** +/* native_loadclasses ********************************************************** - load classes required for native methods + Load classes required for native methods. *******************************************************************************/ -void native_loadclasses() +bool native_init(void) { - static int classesLoaded = 0; /*temporary hack JoWenn*/ +#if !defined(WITH_STATIC_CLASSPATH) void *p; - if (classesLoaded) - return; - - classesLoaded = 1; + /* We need to access the dummy native table, not only to remove a + warning but to be sure that the table is not optimized away + (gcc does this since 3.4). */ -#if !defined(STATIC_CLASSPATH) - /* We need to access the dummy native table, not only to remove a warning */ - /* but to be sure that the table is not optimized away (gcc does this */ - /* since 3.4). */ p = &dummynativetable; -#endif - class_java_lang_Cloneable = - class_new(utf_new_char("java/lang/Cloneable")); - class_load(class_java_lang_Cloneable); - class_link(class_java_lang_Cloneable); - - class_java_lang_Class = - class_new(utf_new_char("java/lang/Class")); - class_load(class_java_lang_Class); - class_link(class_java_lang_Class); - - class_java_lang_VMClass = - class_new(utf_new_char("java/lang/VMClass")); - class_load(class_java_lang_VMClass); - class_link(class_java_lang_VMClass); - - class_java_lang_ClassLoader = - class_new(utf_new_char("java/lang/ClassLoader")); - class_load(class_java_lang_ClassLoader); - class_link(class_java_lang_ClassLoader); - - /* load classes for wrapping primitive types */ - class_java_lang_Double = class_new(utf_new_char("java/lang/Double")); - class_load(class_java_lang_Double); - class_link(class_java_lang_Double); - - class_java_lang_Float = class_new(utf_new_char("java/lang/Float")); - class_load(class_java_lang_Float); - class_link(class_java_lang_Float); - - class_java_lang_Character = class_new(utf_new_char("java/lang/Character")); - class_load(class_java_lang_Character); - class_link(class_java_lang_Character); - - class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer")); - class_load(class_java_lang_Integer); - class_link(class_java_lang_Integer); - - class_java_lang_Long = class_new(utf_new_char("java/lang/Long")); - class_load(class_java_lang_Long); - class_link(class_java_lang_Long); - - class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte")); - class_load(class_java_lang_Byte); - class_link(class_java_lang_Byte); - - class_java_lang_Short = class_new(utf_new_char("java/lang/Short")); - class_load(class_java_lang_Short); - class_link(class_java_lang_Short); - - class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean")); - class_load(class_java_lang_Boolean); - class_link(class_java_lang_Boolean); - - class_java_lang_Void = class_new(utf_new_char("java/lang/Void")); - class_load(class_java_lang_Void); - class_link(class_java_lang_Void); -} + /* initialize libltdl */ + if (lt_dlinit()) { + /* XXX how can we throw an exception here? */ + log_text(lt_dlerror()); -/***************************************************************************** + return false; + } - create systemclassloader object and initialize instance fields + /* get the handle for the main program */ -******************************************************************************/ + if (!(mainhandle = lt_dlopen(NULL))) + return false; -void init_systemclassloader() -{ - if (!SystemClassLoader) { - native_loadclasses(); + /* initialize library hashtable, 10 entries should be enough */ - /* create object and call initializer */ - SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader"))); + hashtable_library = NEW(hashtable); - /* systemclassloader has no parent */ - SystemClassLoader->parent = NULL; - SystemClassLoader->initialized = true; - } -} + hashtable_create(hashtable_library, 10); +#endif + /* everything's ok */ -/*********************** Function: native_findfunction ************************* + return true; +} - 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) - Remark: For faster operation, the names/descriptors are converted from C - strings to Unicode the first time this function is called. +/* native_hashtable_library_add ************************************************ + + Adds an entry to the native library hashtable. *******************************************************************************/ -functionptr native_findfunction(utf *cname, utf *mname, - utf *desc, bool isstatic) +#if !defined(WITH_STATIC_CLASSPATH) +void native_hashtable_library_add(utf *filename, java_objectheader *loader, + lt_dlhandle handle) { -#ifdef STATIC_CLASSPATH - int i; - /* entry of table for fast string comparison */ - struct nativecompref *n; - /* for warning message if no function is found */ - char *buffer; - int buffer_len; + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ - 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); - nativecomptable[i].isstatic = - nativetable[i].isstatic; - nativecomptable[i].func = - nativetable[i].func; - } - nativecompdone = true; - } - -#ifdef JOWENN_DEBUG - buffer_len = - utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64; - - buffer = MNEW(char, buffer_len); + LOCK_MONITOR_ENTER(hashtable_library->header); - strcpy(buffer, "searching matching function in native table:"); - utf_sprint(buffer+strlen(buffer), mname); - strcpy(buffer+strlen(buffer), ": "); - utf_sprint(buffer+strlen(buffer), desc); - strcpy(buffer+strlen(buffer), " for class "); - utf_sprint(buffer+strlen(buffer), cname); + /* normally addresses are aligned to 4, 8 or 16 bytes */ - log_text(buffer); - - MFREE(buffer, char, buffer_len); -#endif - - for (i = 0; i < NATIVETABLESIZE; i++) { - n = &(nativecomptable[i]); - - if (cname == n->classname && mname == n->methodname && - desc == n->descriptor && isstatic == n->isstatic) - return n->func; -#ifdef JOWENN_DEBUG - else { - if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch"); - - else { - buffer_len = - utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64; - - buffer = MNEW(char, buffer_len); + key = ((u4) (ptrint) loader) >> 4; /* align to 16-byte boundaries */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; - strcpy(buffer, "comparing with:"); - utf_sprint(buffer+strlen(buffer), n->methodname); - strcpy (buffer+strlen(buffer), ": "); - utf_sprint(buffer+strlen(buffer), n->descriptor); - strcpy(buffer+strlen(buffer), " for class "); - utf_sprint(buffer+strlen(buffer), n->classname); + /* search external hash chain for the entry */ - log_text(buffer); + while (le) { + if (le->loader == loader) + break; - MFREE(buffer, char, buffer_len); - } - } -#endif + le = le->hashlink; /* next element in external chain */ } - - /* no function was found, display warning */ - - buffer_len = - utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64; + /* no loader found? create a new entry */ - buffer = MNEW(char, buffer_len); + if (le == NULL) { + le = NEW(hashtable_library_loader_entry); - strcpy(buffer, "warning: native function "); - utf_sprint(buffer + strlen(buffer), mname); - strcpy(buffer + strlen(buffer), ": "); - utf_sprint(buffer + strlen(buffer), desc); - strcpy(buffer + strlen(buffer), " not found in class "); - utf_sprint(buffer + strlen(buffer), cname); + le->loader = loader; + le->namelink = NULL; - log_text(buffer); + /* insert entry into hashtable */ - MFREE(buffer, char, buffer_len); + le->hashlink = + (hashtable_library_loader_entry *) hashtable_library->ptr[slot]; + hashtable_library->ptr[slot] = le; -/* exit(1); */ + /* update number of hashtable-entries */ - /* keep compiler happy */ - return NULL; -#else -/* dynamic classpath */ - return 0; -#endif -} + hashtable_library->entries++; + } -/********************** function: javastring_new ******************************* + /* search for library name */ - creates a new object of type java/lang/String with the text of - the specified utf8-string + ne = le->namelink; - return: pointer to the string or NULL if memory is exhausted. + while (ne) { + if (ne->name == filename) { + LOCK_MONITOR_EXIT(hashtable_library->header); -*******************************************************************************/ - -java_lang_String *javastring_new(utf *u) -{ - char *utf_ptr; /* current utf character in utf string */ - u4 utflength; /* length of utf-string if uncompressed */ - java_lang_String *s; /* result-string */ - java_chararray *a; - s4 i; + return; + } - if (!u) { - *exceptionptr = new_nullpointerexception(); - return NULL; + ne = ne->hashlink; /* next element in external chain */ } - utf_ptr = u->text; - utflength = utf_strlen(u); + /* not found? add the library name to the classloader */ - s = (java_lang_String *) builtin_new(class_java_lang_String); - a = builtin_newarray_char(utflength); + ne = NEW(hashtable_library_name_entry); - /* javastring or character-array could not be created */ - if (!a || !s) - return NULL; + ne->name = filename; + ne->handle = handle; - /* decompress utf-string */ - for (i = 0; i < utflength; i++) - a->data[i] = utf_nextu2(&utf_ptr); - - /* set fields of the javastring-object */ - s->value = a; - s->offset = 0; - s->count = utflength; + /* insert entry into external chain */ - return s; -} + ne->hashlink = le->namelink; + le->namelink = ne; + LOCK_MONITOR_EXIT(hashtable_library->header); +} +#endif /* !defined(WITH_STATIC_CLASSPATH) */ -/********************** function: javastring_new_char ************************** - creates a new java/lang/String object which contains the convertet - C-string passed via text. +/* native_hashtable_library_find *********************************************** - return: the object pointer or NULL if memory is exhausted. + Find an entry in the native library hashtable. *******************************************************************************/ -java_lang_String *javastring_new_char(char *text) +#if !defined(WITH_STATIC_CLASSPATH) +hashtable_library_name_entry *native_hashtable_library_find(utf *filename, + java_objectheader *loader) { - s4 i; - s4 len; /* length of the string */ - java_lang_String *s; /* result-string */ - java_chararray *a; - - if (!text) { - *exceptionptr = new_nullpointerexception(); - return NULL; - } + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ - len = strlen(text); + /* normally addresses are aligned to 4, 8 or 16 bytes */ - s = (java_lang_String *) builtin_new(class_java_lang_String); - a = builtin_newarray_char(len); - - /* javastring or character-array could not be created */ - if (!a || !s) - return NULL; - - /* copy text */ - for (i = 0; i < len; i++) - a->data[i] = text[i]; - - /* set fields of the javastring-object */ - s->value = a; - s->offset = 0; - s->count = len; - - return s; -} + 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 */ -/************************* function javastring_tochar ************************** + while (le) { + if (le->loader == loader) + break; - converts a Java string into a C string. - - return: pointer to C string - - Caution: every call of this function overwrites the previous string !!! - -*******************************************************************************/ + le = le->hashlink; /* next element in external chain */ + } -static char stringbuffer[MAXSTRINGSIZE]; + /* no loader found? return NULL */ -char *javastring_tochar(java_objectheader *so) -{ - java_lang_String *s = (java_lang_String *) so; - java_chararray *a; - s4 i; - - if (!s) - return ""; + if (!le) + return NULL; - a = s->value; + /* search for library name */ - if (!a) - return ""; + ne = le->namelink; - if (s->count > MAXSTRINGSIZE) - return ""; + while (ne) { + if (ne->name == filename) + return ne; - for (i = 0; i < s->count; i++) - stringbuffer[i] = a->data[s->offset + i]; + ne = ne->hashlink; /* next element in external chain */ + } - stringbuffer[i] = '\0'; + /* return entry, if no entry was found, ne is NULL */ - return stringbuffer; + return ne; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ -/****************** function class_findfield_approx **************************** - - searches in 'classinfo'-structure for a field with the - specified name - -*******************************************************************************/ - -fieldinfo *class_findfield_approx(classinfo *c, utf *name) -{ - s4 i; - - for (i = 0; i < c->fieldscount; i++) { - /* compare field names */ - if ((c->fields[i].name == name)) - return &(c->fields[i]); - } +/* native_findfunction ********************************************************* - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); + 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) - return NULL; -} + Remark: For faster operation, the names/descriptors are converted + from C strings to Unicode the first time this function is called. +*******************************************************************************/ -s4 class_findfield_index_approx(classinfo *c, utf *name) +#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; - for (i = 0; i < c->fieldscount; i++) { - /* compare field names */ - if ((c->fields[i].name == name)) - return i; - } - - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); - - return -1; -} - - -/********************** function: native_new_and_init ************************* + isstatic = isstatic ? true : false; + + if (!nativecompdone) { + for (i = 0; i < NATIVETABLESIZE; i++) { + nativecomptable[i].classname = + utf_new_char(nativetable[i].classname); - Creates a new object on the heap and calls the initializer. - Returns the object pointer or NULL if memory is exhausted. - -*******************************************************************************/ + nativecomptable[i].methodname = + utf_new_char(nativetable[i].methodname); -java_objectheader *native_new_and_init(classinfo *c) -{ - methodinfo *m; - java_objectheader *o; + nativecomptable[i].descriptor = + utf_new_char(nativetable[i].descriptor); - if (!c) - return *exceptionptr; + nativecomptable[i].isstatic = nativetable[i].isstatic; + nativecomptable[i].func = nativetable[i].func; + } - o = builtin_new(c); /* create object */ - - if (!o) - return NULL; + nativecompdone = true; + } - /* find initializer */ + for (i = 0; i < NATIVETABLESIZE; i++) { + n = &(nativecomptable[i]); - m = class_findmethod(c, - utf_new_char(""), - utf_new_char("()V")); - - if (!m) { /* initializer not found */ - if (opt_verbose) { - char logtext[MAXLOGTEXT]; - sprintf(logtext, "Warning: class has no instance-initializer: "); - utf_sprint_classname(logtext + strlen(logtext), c->name); - log_text(logtext); - } - return o; + if (cname == n->classname && mname == n->methodname && + desc == n->descriptor && isstatic == n->isstatic) + return n->func; } - /* call initializer */ + + /* no function was found, throw exception */ - asm_calljavafunction(m, o, NULL, NULL, NULL); + *exceptionptr = + new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError, + mname); - return o; + return NULL; } +#endif /* defined(WITH_STATIC_CLASSPATH) */ -java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) -{ - methodinfo *m; - java_objectheader *o; +/* native_make_overloaded_function ********************************************* - if (!c) - return *exceptionptr; + XXX - o = builtin_new(c); /* create object */ +*******************************************************************************/ - if (!o) - return NULL; +#if !defined(WITH_STATIC_CLASSPATH) +static char *native_make_overloaded_function(char *name, utf *desc) +{ + char *newname; + s4 namelen; + char *utf_ptr; + u2 c; + s4 i; + + utf_ptr = desc->text; + namelen = strlen(name) + strlen("__") + strlen("0"); + + /* calculate additional length */ + + while ((c = utf_nextu2(&utf_ptr)) != ')') { + switch (c) { + case 'Z': + case 'B': + case 'C': + case 'S': + case 'I': + case 'J': + case 'F': + case 'D': + namelen++; + break; + case '[': + namelen += 2; + break; + case 'L': + namelen++; + while (utf_nextu2(&utf_ptr) != ';') + namelen++; + namelen += 2; + break; + case '(': + break; + default: + assert(0); + } + } - /* find initializer */ - m = class_findmethod(c, - utf_new_char(""), - utf_new_char("(Ljava/lang/String;)V")); - - if (!m) { /* initializer not found */ - if (opt_verbose) { - char logtext[MAXLOGTEXT]; - sprintf(logtext, "Warning: class has no instance-initializer: "); - utf_sprint_classname(logtext + strlen(logtext), c->name); - log_text(logtext); + /* reallocate memory */ + + i = strlen(name); + + newname = DMNEW(char, namelen); + MCOPY(newname, name, char, i); + + utf_ptr = desc->text; + + newname[i++] = '_'; + newname[i++] = '_'; + + while ((c = utf_nextu2(&utf_ptr)) != ')') { + switch (c) { + case 'Z': + case 'B': + case 'C': + case 'S': + case 'J': + case 'I': + case 'F': + case 'D': + newname[i++] = c; + break; + case '[': + newname[i++] = '_'; + newname[i++] = '3'; + break; + case 'L': + newname[i++] = 'L'; + while ((c = utf_nextu2(&utf_ptr)) != ';') + if (((c >= 'a') && (c <= 'z')) || + ((c >= 'A') && (c <= 'Z')) || + ((c >= '0') && (c <= '9'))) + newname[i++] = c; + else + newname[i++] = '_'; + newname[i++] = '_'; + newname[i++] = '2'; + break; + case '(': + break; + default: + assert(0); } - return o; } - /* call initializer */ + /* close string */ - asm_calljavafunction(m, o, s, NULL, NULL); + newname[i] = '\0'; - return o; + return newname; } -java_objectheader *native_new_and_init_int(classinfo *c, s4 i) -{ - methodinfo *m; - java_objectheader *o; +/* native_resolve_function ***************************************************** - if (!c) - return *exceptionptr; - - o = builtin_new(c); /* create object */ - - if (!o) return NULL; + Resolves a native function, maybe from a dynamic library. - /* find initializer */ +*******************************************************************************/ - m = class_findmethod(c, - utf_new_char(""), - utf_new_char("(I)V")); - - if (!m) { /* initializer not found */ - if (opt_verbose) { - char logtext[MAXLOGTEXT]; - sprintf(logtext, "Warning: class has no instance-initializer: "); - utf_sprint_classname(logtext + strlen(logtext), c->name); - log_text(logtext); - } - return o; +functionptr native_resolve_function(methodinfo *m) +{ + 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; + + + /* 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(" ... "); } + + /* calculate length of native function name */ - /* call initializer */ - -#if defined(__I386__) || defined(__POWERPC__) - asm_calljavafunction(m, o, (void *) i, NULL, NULL); -#else - asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL); -#endif + namelen = strlen("Java_") + utf_get_number_of_u2s(m->class->name) + strlen("_") + + utf_get_number_of_u2s(m->name) + strlen("0"); - return o; -} + /* check for underscores in class name */ + utf_ptr = m->class->name->text; + utf_endptr = UTF_END(m->class->name); -java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) -{ - methodinfo *m; - java_objectheader *o; - - if (!c) - return *exceptionptr; + while (utf_ptr < utf_endptr) + if (utf_nextu2(&utf_ptr) == '_') + namelen++; - o = builtin_new(c); /* create object */ - - if (!o) return NULL; + /* check for underscores in method name */ - /* find initializer */ + utf_ptr = m->name->text; + utf_endptr = UTF_END(m->name); - m = class_findmethod(c, - utf_new_char(""), - utf_new_char("(Ljava/lang/Throwable;)V")); - - if (!m) { /* initializer not found */ - if (opt_verbose) { - char logtext[MAXLOGTEXT]; - sprintf(logtext, "Warning: class has no instance-initializer: "); - utf_sprint_classname(logtext + strlen(logtext), c->name); - log_text(logtext); - } - return o; - } + while (utf_ptr < utf_endptr) + if (utf_nextu2(&utf_ptr) == '_') + namelen++; - /* call initializer */ + /* allocate memory */ - asm_calljavafunction(m, o, t, NULL, NULL); + dumpsize = dump_size(); - return o; -} + name = DMNEW(char, namelen); -/******************** function: stringtable_update **************************** + /* generate name of native functions */ - traverses the javastring hashtable and sets the vftbl-entries of - javastrings which were temporarily set to NULL, because - java.lang.Object was not yet loaded + strcpy(name, "Java_"); + i = strlen("Java_"); -*******************************************************************************/ - -void stringtable_update () -{ - java_lang_String *js; - java_chararray *a; - literalstring *s; /* hashtable entry */ - int i; - - for (i = 0; i < string_hash.size; i++) { - s = string_hash.ptr[i]; - if (s) { - while (s) { - - js = (java_lang_String *) s->string; - - if (!js || !js->value) - /* error in hashtable found */ - panic("invalid literalstring in hashtable"); - - a = js->value; - - if (!js->header.vftbl) - /* vftbl of javastring is NULL */ - js->header.vftbl = class_java_lang_String->vftbl; - - if (!a->header.objheader.vftbl) - /* vftbl of character-array is NULL */ - a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; - - /* follow link in external hash chain */ - s = s->hashlink; - } - } - } -} + utf_ptr = m->class->name->text; + utf_endptr = UTF_END(m->class->name); + for (; utf_ptr < utf_endptr; utf_ptr++, i++) { + name[i] = *utf_ptr; -/************************* function: u2_utflength *************************** + /* escape sequence for '_' is '_1' */ - returns the utf length in bytes of a u2 array + if (name[i] == '_') + name[++i] = '1'; -*****************************************************************************/ + /* replace '/' with '_' */ -u4 u2_utflength(u2 *text, u4 u2_length) -{ - u4 result_len = 0; /* utf length in bytes */ - u2 ch; /* current unicode character */ - u4 len; - - for (len = 0; len < u2_length; len++) { - /* next unicode character */ - ch = *text++; - - /* determine bytes required to store unicode character as utf */ - if (ch && (ch < 0x80)) - result_len++; - else if (ch < 0x800) - result_len += 2; - else - result_len += 3; + if (name[i] == '/') + name[i] = '_'; } - return result_len; -} + /* seperator between class and method */ + name[i++] = '_'; -/********************* function: utf_new_u2 *********************************** + utf_ptr = m->name->text; + utf_endptr = UTF_END(m->name); - make utf symbol from u2 array, - if isclassname is true '.' is replaced by '/' + for (; utf_ptr < utf_endptr; utf_ptr++, i++) { + name[i] = *utf_ptr; -*******************************************************************************/ + /* escape sequence for '_' is '_1' */ -utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname) -{ - char *buffer; /* memory buffer for unicode characters */ - char *pos; /* pointer to current position in buffer */ - u4 left; /* unicode characters left */ - u4 buflength; /* utf length in bytes of the u2 array */ - utf *result; /* resulting utf-string */ - int i; - - /* determine utf length in bytes and allocate memory */ - /* printf("utf_new_u2: unicode_length=%d\n",unicode_length); */ - buflength = u2_utflength(unicode_pos, unicode_length); - buffer = MNEW(char, buflength); - - left = buflength; - pos = buffer; - - for (i = 0; i++ < unicode_length; unicode_pos++) { - /* next unicode character */ - u2 c = *unicode_pos; - - if ((c != 0) && (c < 0x80)) { - /* 1 character */ - left--; - if ((int) left < 0) break; - /* convert classname */ - if (isclassname && c == '.') - *pos++ = '/'; - else - *pos++ = (char) c; - - } else if (c < 0x800) { - /* 2 characters */ - unsigned char high = c >> 6; - unsigned char low = c & 0x3F; - left = left - 2; - if ((int) left < 0) break; - *pos++ = high | 0xC0; - *pos++ = low | 0x80; - - } else { - /* 3 characters */ - char low = c & 0x3f; - char mid = (c >> 6) & 0x3F; - char high = c >> 12; - left = left - 3; - if ((int) left < 0) break; - *pos++ = high | 0xE0; - *pos++ = mid | 0x80; - *pos++ = low | 0x80; - } + if (name[i] == '_') + name[++i] = '1'; } - - /* insert utf-string into symbol-table */ - result = utf_new(buffer,buflength); - MFREE(buffer, char, buflength); + /* close string */ - return result; -} + name[i] = '\0'; -/********************* function: javastring_toutf ***************************** + /* generate overloaded function (having the types in it's name) */ - make utf symbol from javastring + newname = native_make_overloaded_function(name, m->descriptor); -*******************************************************************************/ - -utf *javastring_toutf(java_lang_String *string, bool isclassname) -{ - java_lang_String *str = (java_lang_String *) string; + /* check the library hash entries of the classloader of the + methods's class */ -/* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */ -/* fflush(stdout); */ + sym = NULL; - return utf_new_u2(str->value->data + str->offset, str->count, isclassname); -} + /* normally addresses are aligned to 4, 8 or 16 bytes */ + key = ((u4) (ptrint) m->class->classloader) >> 4; /* align to 16-byte */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; -/********************* function: literalstring_u2 ***************************** + /* iterate through loaders in this hash slot */ - searches for the javastring with the specified u2-array in - the string hashtable, if there is no such string a new one is - created + while ((le != NULL) && (sym == NULL)) { + /* iterate through names in this loader */ - if copymode is true a copy of the u2-array is made + ne = le->namelink; + + while ((ne != NULL) && (sym == NULL)) { + sym = lt_dlsym(ne->handle, name); -*******************************************************************************/ + if (sym == NULL) + sym = lt_dlsym(ne->handle, newname); -java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, - bool copymode) -{ - literalstring *s; /* hashtable element */ - java_lang_String *js; /* u2-array wrapped in javastring */ - java_chararray *stringdata; /* copy of u2-array */ - u4 key; - u4 slot; - u2 i; - -/* #define DEBUG_LITERALSTRING_U2 */ -#ifdef DEBUG_LITERALSTRING_U2 - printf("literalstring_u2: length=%d, offset=%d\n", length, offset); - fflush(stdout); -#endif - - /* find location in hashtable */ - key = unicode_hashkey(a->data + offset, length); - slot = key & (string_hash.size - 1); - s = string_hash.ptr[slot]; - - while (s) { - js = (java_lang_String *) s->string; - - if (length == js->count) { - /* compare text */ - for (i = 0; i < length; i++) { - if (a->data[offset + i] != js->value->data[i]) - goto nomatch; - } - - /* string already in hashtable, free memory */ - if (!copymode) - mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10); - -#ifdef DEBUG_LITERALSTRING_U2 - printf("literalstring_u2: foundentry at %p\n", js); - utf_display(javastring_toutf(js, 0)); - printf("\n\n"); - fflush(stdout); -#endif - return (java_objectheader *) js; + ne = ne->hashlink; } - nomatch: - /* follow link in external hash chain */ - s = s->hashlink; - } - - if (copymode) { - /* create copy of u2-array for new javastring */ - u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10; - stringdata = mem_alloc(arraysize); -/* memcpy(stringdata, a, arraysize); */ - memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader)); - memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10); - - } else { - stringdata = a; + le = le->hashlink; } - /* location in hashtable found, complete arrayheader */ - stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; - stringdata->header.size = length; + if (sym != NULL) + if (opt_verbosejni) + printf("JNI ]\n"); - /* if we use eager loading, we have to check loaded String class */ - if (opt_eager) { - class_java_lang_String = - class_new_intern(utf_new_char("java/lang/String")); - if (!class_load(class_java_lang_String)) - return NULL; + /* If not found, try to find the native function symbol in the + main program. */ - list_addfirst(&unlinkedclasses, class_java_lang_String); - } + if (sym == NULL) { + sym = lt_dlsym(mainhandle, name); - /* create new javastring */ - js = NEW(java_lang_String); -#if defined(USE_THREADS) && defined(NATIVE_THREADS) - initObjectLock(&js->header); -#endif - js->header.vftbl = class_java_lang_String->vftbl; - js->value = stringdata; - js->offset = 0; - js->count = length; - -#ifdef DEBUG_LITERALSTRING_U2 - printf("literalstring_u2: newly created at %p\n", js); - utf_display(javastring_toutf(js, 0)); - printf("\n\n"); - fflush(stdout); -#endif - - /* create new literalstring */ - s = NEW(literalstring); - s->hashlink = string_hash.ptr[slot]; - s->string = (java_objectheader *) js; - string_hash.ptr[slot] = s; - - /* update number of hashtable entries */ - string_hash.entries++; - - /* reorganization of hashtable */ - if (string_hash.entries > (string_hash.size * 2)) { - /* reorganization of hashtable, average length of - the external chains is approx. 2 */ - - u4 i; - literalstring *s; - hashtable newhash; /* the new hashtable */ - - /* create new hashtable, double the size */ - init_hashtable(&newhash, string_hash.size * 2); - newhash.entries = string_hash.entries; - - /* transfer elements to new hashtable */ - for (i = 0; i < string_hash.size; i++) { - s = string_hash.ptr[i]; - while (s) { - literalstring *nexts = s->hashlink; - js = (java_lang_String *) s->string; - slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1); - - s->hashlink = newhash.ptr[slot]; - newhash.ptr[slot] = s; - - /* follow link in external hash chain */ - s = nexts; - } - } - - /* dispose old table */ - MFREE(string_hash.ptr, void*, string_hash.size); - string_hash = newhash; - } + if (sym == NULL) + sym = lt_dlsym(mainhandle, newname); - return (java_objectheader *) js; -} + if (sym != NULL) + if (opt_verbosejni) + printf("internal ]\n"); + } -/******************** Function: literalstring_new ***************************** +#if defined(ENABLE_JVMTI) + /* fire Native Method Bind event */ + if (jvmti) jvmti_NativeMethodBind(m, sym, &sym); +#endif - creates a new javastring with the text of the utf-symbol - and inserts it into the string hashtable + /* no symbol found? throw exception */ -*******************************************************************************/ + if (sym == NULL) { + if (opt_verbosejni) + printf("failed ]\n"); -java_objectheader *literalstring_new(utf *u) -{ - char *utf_ptr = u->text; /* pointer to current unicode character in utf string */ - u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */ - java_chararray *a; /* u2-array constructed from utf string */ - u4 i; + *exceptionptr = + new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError, + m->name); + } - /* allocate memory */ - a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10); + /* release memory */ - /* convert utf-string to u2-array */ - for (i = 0; i < utflength; i++) - a->data[i] = utf_nextu2(&utf_ptr); + dump_release(dumpsize); - return literalstring_u2(a, utflength, 0, false); + return (functionptr) (ptrint) sym; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ -/********************** function: literalstring_free ************************** - - removes a javastring from memory +/* 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. + +*******************************************************************************/ -void literalstring_free(java_objectheader* sobj) +java_objectheader *native_new_and_init(classinfo *c) { - java_lang_String *s = (java_lang_String *) sobj; - java_chararray *a = s->value; + methodinfo *m; + java_objectheader *o; - /* dispose memory of java.lang.String object */ - FREE(s, java_lang_String); + if (!c) + return *exceptionptr; - /* dispose memory of java-characterarray */ - FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */ -} + /* create object */ + o = builtin_new(c); + + if (!o) + return NULL; -void copy_vftbl(vftbl_t **dest, vftbl_t *src) -{ - *dest = src; -#if 0 - /* XXX this kind of copying does not work (in the general - * case). The interface tables would have to be copied, too. I - * don't see why we should make a copy anyway. -Edwin - */ - *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1)); - memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr)); - memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr)); -#endif -} + /* try to find the initializer */ + m = class_findmethod(c, utf_init, utf_void__void); + + /* ATTENTION: returning the object here is ok, since the class may + not have an initializer */ -/****************************************************************************************** + if (!m) + return o; - creates method signature (excluding return type) from array of - class-objects representing the parameters of the method + /* call initializer */ -*******************************************************************************************/ + (void) vm_call_method(m, o); + return o; +} -utf *create_methodsig(java_objectarray* types, char *retType) -{ - char *buffer; /* buffer for building the desciptor */ - char *pos; /* current position in buffer */ - utf *result; /* the method signature */ - u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */ - u4 i, j; - - if (!types) return NULL; - - /* determine required buffer-size */ - for (i = 0; i < types->header.size; i++) { - classinfo *c = (classinfo *) types->data[i]; - buffer_size = buffer_size + c->name->blength + 2; - } - - if (retType) buffer_size += strlen(retType); - - /* allocate buffer */ - buffer = MNEW(char, buffer_size); - pos = buffer; - - /* method-desciptor starts with parenthesis */ - *pos++ = '('; - - for (i = 0; i < types->header.size; i++) { - char ch; - - /* current argument */ - classinfo *c = (classinfo *) types->data[i]; - - /* current position in utf-text */ - char *utf_ptr = c->name->text; - - /* determine type of argument */ - if ((ch = utf_nextu2(&utf_ptr)) == '[') { - /* arrayclass */ - for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) { - *pos++ = *utf_ptr; /* copy text */ - } - - } else { - /* check for primitive types */ - for (j = 0; j < PRIMITIVETYPE_COUNT; j++) { - char *utf_pos = utf_ptr - 1; - char *primitive = primitivetype_table[j].wrapname; - - /* compare text */ - while (utf_pos < utf_end(c->name)) { - if (*utf_pos++ != *primitive++) goto nomatch; - } - - /* primitive type found */ - *pos++ = primitivetype_table[j].typesig; - goto next_type; - - nomatch: - ; - } - - /* no primitive type and no arrayclass, so must be object */ - *pos++ = 'L'; - - /* copy text */ - for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) { - *pos++ = *utf_ptr; - } - - *pos++ = ';'; - - next_type: - ; - } - } - - *pos++ = ')'; - - if (retType) { - for (i = 0; i < strlen(retType); i++) { - *pos++ = retType[i]; - } - } - /* create utf-string */ - result = utf_new(buffer, (pos - buffer)); - MFREE(buffer, char, buffer_size); +java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) +{ + methodinfo *m; + java_objectheader *o; - return result; -} + if (!c) + return *exceptionptr; + /* create object */ -/****************************************************************************************** + o = builtin_new(c); - retrieve the next argument or returntype from a descriptor - and return the corresponding class + if (!o) + return NULL; -*******************************************************************************************/ + /* find initializer */ -classinfo *get_type(char **utf_ptr,char *desc_end, bool skip) -{ - classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr, - (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD); - if (!c) - /* unknown type */ - panic("illegal descriptor"); + m = class_resolveclassmethod(c, + utf_init, + utf_java_lang_String__void, + NULL, + true); - if (skip) return NULL; + /* initializer not found */ - use_class_as_object(c); - return c; -} + if (!m) + return NULL; + /* call initializer */ -/* get_parametertypes ********************************************************** + (void) vm_call_method(m, o, s); - use the descriptor of a method to generate a java/lang/Class array - which contains the classes of the parametertypes of the method + return o; +} -*******************************************************************************/ -java_objectarray* get_parametertypes(methodinfo *m) +java_objectheader *native_new_and_init_int(classinfo *c, s4 i) { - utf *descr = m->descriptor; /* method-descriptor */ - char *utf_ptr = descr->text; /* current position in utf-text */ - char *desc_end = utf_end(descr); /* points behind utf string */ - java_objectarray* result; - int parametercount = 0; - int i; - - /* skip '(' */ - utf_nextu2(&utf_ptr); - - /* determine number of parameters */ - while (*utf_ptr != ')') { - get_type(&utf_ptr, desc_end, true); - parametercount++; - } - - /* create class-array */ - result = builtin_anewarray(parametercount, class_java_lang_Class); - - utf_ptr = descr->text; - utf_nextu2(&utf_ptr); - - /* get returntype classes */ - for (i = 0; i < parametercount; i++) - result->data[i] = - (java_objectheader *) get_type(&utf_ptr, desc_end, false); - - return result; -} + methodinfo *m; + java_objectheader *o; + if (!c) + return *exceptionptr; -/* get_exceptiontypes ********************************************************** + /* create object */ - get the exceptions which can be thrown by a method + o = builtin_new(c); + + if (!o) + return NULL; -*******************************************************************************/ + /* find initializer */ -java_objectarray* get_exceptiontypes(methodinfo *m) -{ - u2 excount; - u2 i; - java_objectarray *result; + m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true); - excount = m->thrownexceptionscount; + /* initializer not found */ - /* create class-array */ - result = builtin_anewarray(excount, class_java_lang_Class); + if (!m) + return NULL; - for (i = 0; i < excount; i++) { - java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]); - use_class_as_object((classinfo *) o); - result->data[i] = o; - } + /* call initializer */ - return result; + (void) vm_call_method(m, o, i); + + return o; } +java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) +{ + methodinfo *m; + java_objectheader *o; + if (!c) + return *exceptionptr; + /* create object */ -/****************************************************************************************** + o = builtin_new(c); + + if (!o) + return NULL; - get the returntype class of a method + /* find initializer */ -*******************************************************************************************/ + m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void); + + /* initializer not found */ -classinfo *get_returntype(methodinfo *m) -{ - char *utf_ptr; /* current position in utf-text */ - char *desc_end; /* points behind utf string */ - utf *desc = m->descriptor; /* method-descriptor */ + if (!m) + return NULL; - utf_ptr = desc->text; - desc_end = utf_end(desc); + /* call initializer */ - /* ignore parametertypes */ - while ((utf_ptraCalled = %s %s %s\n",i,j, - nc.methods[i].methodCalls[j].classname, - nc.methods[i].methodCalls[j].methodname, - nc.methods[i].methodCalls[j].descriptor);fflush(stdout); - } - } - printf("-+++++--------------------\n");fflush(stdout); -} + md = m->parseddesc; -/*--------------------------------------------------------*/ -void printCompNativeCall(nativeCompCall nc) { - int i,j; - printf("printCompNativeCall BEGIN\n");fflush(stdout); - printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout); - utf_display(nc.classname); fflush(stdout); - - for (i=0; itext,nc.methods[i].descriptor->text);fflush(stdout); - utf_display(nc.methods[i].methodname); fflush(stdout); - utf_display(nc.methods[i].descriptor);fflush(stdout); - printf("\n");fflush(stdout); - - for (j=0; jbCalled = ",i,j);fflush(stdout); - utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout); - utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout); - utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout); - printf("\n");fflush(stdout); - } - } -printf("---------------------\n");fflush(stdout); -} + /* is the descriptor fully parsed? */ + if (!m->parseddesc->params) + if (!descriptor_params_from_paramtypes(md, m->flags)) + return NULL; -/*--------------------------------------------------------*/ -classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) -{ - int i = 0; - int j = 0; - int cnt = 0; - classMeth mc; - mc.i_class = i; - mc.j_method = j; - mc.methCnt = cnt; - - return mc; -} + paramtypes = md->paramtypes; + paramcount = md->paramcount; -/*--------------------------------------------------------*/ -nativeCall* findNativeClassCalls(char *aclassname ) { -int i; + /* skip `this' pointer */ -for (i=0;iflags & ACC_STATIC)) { + paramtypes++; + paramcount--; + } -return NULL; -} -/*--------------------------------------------------------*/ -/*--------------------------------------------------------*/ -void utfNativeCall(nativeCall nc, nativeCompCall *ncc) { - int i,j; - - - ncc->classname = utf_new_char(nc.classname); - ncc->methCnt = nc.methCnt; - - for (i=0; imethods[i].methodname = utf_new_char(nc.methods[i].methodname); - ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor); - ncc->callCnt[i] = nc.callCnt[i]; - - for (j=0; jmethods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname); - - if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) { - ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname); - ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor); - } - else { - ncc->methods[i].methodCalls[j].methodname = NULL; - ncc->methods[i].methodCalls[j].descriptor = NULL; - } - } - } -} + /* create class-array */ + oa = builtin_anewarray(paramcount, class_java_lang_Class); + if (!oa) + return NULL; -/*--------------------------------------------------------*/ + /* get classes */ -bool natcall2utf(bool natcallcompdone) { -int i; + for (i = 0; i < paramcount; i++) + if (!resolve_class_from_typedesc(¶mtypes[i], true, false, + (classinfo **) &oa->data[i])) + return NULL; -if (natcallcompdone) - return true; + return oa; +} -for (i=0;ithrownexceptionscount, class_java_lang_Class); - if (size > 0) { - if (start == class_java_lang_SecurityManager) { - size--; - start--; - } - } + if (!oa) + return NULL; - tmpArray = - builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl); + for (i = 0; i < m->thrownexceptionscount; i++) { + if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[i], + resolveEager, true, false, &c)) + return NULL; - for(i = 0, current = start; i < size; i++, current--) { - c = *current; - /* printf("%d\n",i); - utf_display(c->name);*/ - use_class_as_object(c); - tmpArray->data[i] = (java_objectheader *) c; + oa->data[i] = (java_objectheader *) c; } - return tmpArray; + return oa; } -java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start) -{ -#if defined(__GNUC__) -#warning platform dependend -#endif - int i; - classinfo **current; - classinfo *c; - classinfo *privilegedAction; - size_t size; - - size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*); - - /* log_text("builtin_asm_getclassloader"); - printf("end %p, start %p, size %ld\n",end,start,size);*/ - - if (!class_java_lang_SecurityManager) - class_java_lang_SecurityManager = - class_new(utf_new_char("java/lang/SecurityManager")); - - if (size > 0) { - if (start == class_java_lang_SecurityManager) { - size--; - start--; - } - } - - privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction")); +/* native_get_returntype ******************************************************* - for(i = 0, current = start; i < size; i++, current--) { - c = *current; + Get the returntype class of a method. - if (c == privilegedAction) - return NULL; - - if (c->classloader) - return (java_lang_ClassLoader *) c->classloader; - } +*******************************************************************************/ - return NULL; +classinfo *native_get_returntype(methodinfo *m) +{ + classinfo *c; - /* - log_text("Java_java_lang_VMSecurityManager_currentClassLoader"); - init_systemclassloader(); + if (!resolve_class_from_typedesc(&(m->parseddesc->returntype), true, false, + &c)) + return NULL; - return SystemClassLoader;*/ + return c; }