X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fnative%2Fnative.c;h=a71c7383dcb9aced0ffe47822b26ab0bd54fa61f;hb=a3194739a44a0ac20fdd805e05e7f769786a9c81;hp=1ab67dbe1d4f78ac3fb6227ad82dc8702afe37e0;hpb=d75b6037acf17c342166b9c9bd6e657dfdd12cd9;p=cacao.git diff --git a/src/native/native.c b/src/native/native.c index 1ab67dbe1..a71c7383d 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, 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 This file is part of CACAO. @@ -19,1487 +19,1219 @@ 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 - - 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. - - $Id: native.c 1735 2004-12-07 14:33:27Z twisti $ + $Id: native.c 7305 2007-02-09 11:08:14Z twisti $ */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "config.h" -/* Include files for IO functions */ +#include +#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_String.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/hashtable.h" #include "toolbox/logging.h" + #include "vm/builtin.h" #include "vm/exceptions.h" #include "vm/global.h" -#include "vm/loader.h" -#include "vm/options.h" -#include "vm/tables.h" +#include "vm/stringlocal.h" +#include "vm/vm.h" + #include "vm/jit/asmpart.h" #include "vm/jit/jit.h" -#if 0 -#include "threads/thread.h" -#include "threads/threadio.h" -#include "threads/locks.h" + +#include "vmcore/loader.h" +#include "vmcore/options.h" +#include "vmcore/resolve.h" + +#if defined(ENABLE_JVMTI) +#include "native/jvmti/cacaodbg.h" #endif /* 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_JAVASE) + +#include "native/include/java_io_InputStream.h" +#include "native/include/java_io_PrintStream.h" + +#include "native/include/java_lang_Cloneable.h" +#include "native/include/java_util_Properties.h" + +#include "native/include/java_lang_Object.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_VMClass.h" +#include "native/include/java_security_ProtectionDomain.h" /* required by... */ +#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 -#include "nativetable.inc" +#elif defined(ENABLE_JAVAME_CLDC1_1) +#include "native/include/com_sun_cldchi_io_ConsoleOutputStream.h" +#include "native/include/java_lang_Class.h" +#include "native/include/java_lang_Double.h" +#include "native/include/java_lang_Float.h" +#include "native/include/java_lang_Math.h" +#include "native/include/java_lang_Runtime.h" +#include "native/include/java_lang_System.h" +#include "native/include/java_lang_Thread.h" -/* for java-string to char conversion */ -#define MAXSTRINGSIZE 1000 +#endif +#if defined(WITH_STATIC_CLASSPATH) -/******************** systemclasses required for native methods ***************/ +/* these are required to prevent compiler warnings */ -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; +#include "native/include/java_net_DatagramPacket.h" +#include "native/include/java_net_InetAddress.h" +#include "native/include/java_net_SocketImpl.h" -methodinfo *method_vmclass_init; +#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 */ -/* the system classloader object */ -struct java_lang_ClassLoader *SystemClassLoader = NULL; +#include "native/nativetable.inc" -/* for raising exceptions from native methods */ -#if !defined(USE_THREADS) || !defined(NATIVE_THREADS) -java_objectheader* _exceptionptr = NULL; -#endif +#elif !defined(ENABLE_LIBJVM) -/************* use classinfo structure as java.lang.Class object **************/ +/* dummynativetable ************************************************************ -void use_class_as_object(classinfo *c) -{ - if (!c->classvftbl) { - c->header.vftbl = class_java_lang_Class->vftbl; - c->classvftbl = true; - } - -} + 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! -/************************** tables for methods ********************************/ +*******************************************************************************/ -#undef JOWENN_DEBUG -#undef JOWENN_DEBUG1 +functionptr dummynativetable[] = { +#if defined(ENABLE_JAVASE) + (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 +#endif -#ifdef STATIC_CLASSPATH -#define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref)) +#elif defined(ENABLE_JAVAME_CLDC1_1) + (functionptr) Java_com_sun_cldc_io_ResourceInputStream_open, -/* table for fast string comparison */ -static nativecompref nativecomptable[NATIVETABLESIZE]; + (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_open0, + (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf, + (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte, -/* string comparsion table initialized */ -static bool nativecompdone = false; -#endif + (functionptr) Java_com_sun_cldchi_io_ConsoleOutputStream_write, + (functionptr) Java_java_lang_Class_forName, + (functionptr) Java_java_lang_Class_newInstance, + (functionptr) Java_java_lang_Class_isInstance, + (functionptr) Java_java_lang_Class_isAssignableFrom, + (functionptr) Java_java_lang_Class_isInterface, + (functionptr) Java_java_lang_Class_isArray, + (functionptr) Java_java_lang_Class_getName, -/* XXX don't define this in a header file!!! */ + (functionptr) Java_java_lang_Double_doubleToLongBits, -static struct nativeCall nativeCalls[] = -{ -#include "nativecalls.inc" -}; + (functionptr) Java_java_lang_Float_floatToIntBits, -#define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall)) + (functionptr) Java_java_lang_Math_ceil, + (functionptr) Java_java_lang_Math_cos, + (functionptr) Java_java_lang_Math_floor, + (functionptr) Java_java_lang_Math_sin, + (functionptr) Java_java_lang_Math_sqrt, + (functionptr) Java_java_lang_Math_tan, -struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE]; + (functionptr) Java_java_lang_Object_hashCode, + (functionptr) Java_java_lang_Object_notify, + (functionptr) Java_java_lang_Object_wait, -/******************************************************************************/ + (functionptr) Java_java_lang_Runtime_exitInternal, + (functionptr) Java_java_lang_Runtime_freeMemory, + (functionptr) Java_java_lang_Runtime_totalMemory, + (functionptr) Java_java_lang_Runtime_gc, -/**include "natcalls.h" **/ + (functionptr) Java_java_lang_String_hashCode, + (functionptr) Java_java_lang_String_indexOf__I, + (functionptr) Java_java_lang_String_indexOf__II, + (functionptr) Java_java_lang_String_lastIndexOf__II, + (functionptr) Java_java_lang_String_intern, + (functionptr) Java_java_lang_System_getProperty0, -/*********************** function: native_loadclasses ************************** + (functionptr) Java_java_lang_Thread_currentThread, + (functionptr) Java_java_lang_Thread_setPriority0, + (functionptr) Java_java_lang_Thread_start0, + (functionptr) Java_java_lang_Thread_yield, - load classes required for native methods + (functionptr) Java_java_lang_Throwable_printStackTrace, + (functionptr) Java_java_lang_Throwable_fillInStackTrace +#endif +}; -*******************************************************************************/ +#endif /* defined(ENABLE_LIBJVM) */ -void native_loadclasses() -{ - static int classesLoaded = 0; /*temporary hack JoWenn*/ - if (classesLoaded) - return; +/* tables for methods *********************************************************/ - classesLoaded = 1; +#if defined(WITH_STATIC_CLASSPATH) +#define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref)) - class_java_lang_Cloneable = - class_new(utf_new_char("java/lang/Cloneable")); - class_load(class_java_lang_Cloneable); - class_link(class_java_lang_Cloneable); +/* table for fast string comparison */ +static nativecompref nativecomptable[NATIVETABLESIZE]; - class_java_lang_Class = - class_new(utf_new_char("java/lang/Class")); - class_load(class_java_lang_Class); - class_link(class_java_lang_Class); +/* string comparsion table initialized */ +static bool nativecompdone = false; +#endif - 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); +/* global variables ***********************************************************/ - /* 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); +#if !defined(WITH_STATIC_CLASSPATH) +static hashtable *hashtable_library; +static lt_dlhandle mainhandle; +#endif - 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); +/* native_init ***************************************************************** - class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer")); - class_load(class_java_lang_Integer); - class_link(class_java_lang_Integer); + Initializes the native subsystem. - 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); +bool native_init(void) +{ +#if !defined(WITH_STATIC_CLASSPATH) + /* initialize libltdl */ - class_java_lang_Short = class_new(utf_new_char("java/lang/Short")); - class_load(class_java_lang_Short); - class_link(class_java_lang_Short); + if (lt_dlinit()) + vm_abort("native_init: lt_dlinit failed: %s\n", lt_dlerror()); - class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean")); - class_load(class_java_lang_Boolean); - class_link(class_java_lang_Boolean); + /* Get the handle for the main program or for the libjvm.so, + depends on the configuration. */ - class_java_lang_Void = class_new(utf_new_char("java/lang/Void")); - class_load(class_java_lang_Void); - class_link(class_java_lang_Void); +# if defined(ENABLE_LIBJVM) + /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH. + If not found, try the absolute path. */ -} + if (!(mainhandle = lt_dlopenext("libjvm"))) + if (!(mainhandle = lt_dlopenext(cacao_libjvm))) + vm_abort("native_init: lt_dlopenext failed: %s\n", lt_dlerror()); +# else + if (!(mainhandle = lt_dlopen(NULL))) + vm_abort("native_init: lt_dlopen failed: %s\n", lt_dlerror()); +# endif + /* initialize library hashtable, 10 entries should be enough */ -/***************************************************************************** + hashtable_library = NEW(hashtable); - create systemclassloader object and initialize instance fields + hashtable_create(hashtable_library, 10); +#endif -******************************************************************************/ + /* everything's ok */ -void init_systemclassloader() -{ - log_text("init_systemclassloader"); - if (!SystemClassLoader) { - native_loadclasses(); - log_text("Initializing new system class loader"); - /* create object and call initializer */ - SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_new(utf_new_char("gnu/java/lang/SystemClassLoader"))); - - /* systemclassloader has no parent */ - SystemClassLoader->parent = NULL; - SystemClassLoader->initialized = true; - } - log_text("leaving system class loader"); + return true; } -/*********************** Function: native_findfunction ************************* +/* native_hashtable_library_add ************************************************ - 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. + 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; - - 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); - - 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); + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ - log_text(buffer); + LOCK_MONITOR_ENTER(hashtable_library->header); - MFREE(buffer, char, buffer_len); -#endif - - for (i = 0; i < NATIVETABLESIZE; i++) { - n = &(nativecomptable[i]); + /* normally addresses are aligned to 4, 8 or 16 bytes */ - 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; - - buffer = MNEW(char, buffer_len); + /* no loader found? create a new 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); + if (le == NULL) { + le = NEW(hashtable_library_loader_entry); - log_text(buffer); + le->loader = loader; + le->namelink = NULL; - MFREE(buffer, char, buffer_len); + /* insert entry into hashtable */ -/* exit(1); */ + le->hashlink = + (hashtable_library_loader_entry *) hashtable_library->ptr[slot]; + hashtable_library->ptr[slot] = le; - /* keep compiler happy */ - return NULL; -#else -/* dynamic classpath */ - return 0; -#endif -} + /* update number of hashtable-entries */ + hashtable_library->entries++; + } -/********************** function: javastring_new ******************************* - creates a new object of type java/lang/String with the text of - the specified utf8-string + /* search for library name */ - return: pointer to the string or NULL if memory is exhausted. + ne = le->namelink; -*******************************************************************************/ + 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; + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ - if (!text) { - *exceptionptr = new_nullpointerexception(); - return NULL; - } - - 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; + key = ((u4) (ptrint) loader) >> 4; /* align to 16-byte boundaries */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; - /* 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; + /* search external hash chain for the entry */ - return s; -} + while (le) { + if (le->loader == loader) + break; + le = le->hashlink; /* next element in external chain */ + } -/************************* function javastring_tochar ************************** + /* no loader found? return NULL */ - converts a Java string into a C string. - - return: pointer to C string - - Caution: every call of this function overwrites the previous string !!! - -*******************************************************************************/ + if (!le) + return NULL; -static char stringbuffer[MAXSTRINGSIZE]; + /* search for library name */ -char *javastring_tochar(java_objectheader *so) -{ - java_lang_String *s = (java_lang_String *) so; - java_chararray *a; - s4 i; - - if (!s) - return ""; + ne = le->namelink; - a = s->value; + while (ne) { + if (ne->name == filename) + return ne; - if (!a) - return ""; + ne = ne->hashlink; /* next element in external chain */ + } - if (s->count > MAXSTRINGSIZE) - return ""; + /* return entry, if no entry was found, ne is NULL */ - for (i = 0; i < s->count; i++) - stringbuffer[i] = a->data[s->offset + i]; + return ne; +} +#endif /* !defined(WITH_STATIC_CLASSPATH) */ - stringbuffer[i] = '\0'; - return stringbuffer; -} +/* native_findfunction ********************************************************* + 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) -/****************** function class_findfield_approx **************************** - - searches in 'classinfo'-structure for a field with the - specified name + Remark: For faster operation, the names/descriptors are converted + from C strings to Unicode the first time this function is called. *******************************************************************************/ - -fieldinfo *class_findfield_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 &(c->fields[i]); - } + isstatic = isstatic ? true : false; + + if (!nativecompdone) { + for (i = 0; i < NATIVETABLESIZE; i++) { + nativecomptable[i].classname = + utf_new_char(nativetable[i].classname); - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); + nativecomptable[i].methodname = + utf_new_char(nativetable[i].methodname); - return NULL; -} + nativecomptable[i].descriptor = + utf_new_char(nativetable[i].descriptor); + nativecomptable[i].isstatic = nativetable[i].isstatic; + nativecomptable[i].func = nativetable[i].func; + } -s4 class_findfield_index_approx(classinfo *c, utf *name) -{ - s4 i; + nativecompdone = true; + } + + for (i = 0; i < NATIVETABLESIZE; i++) { + n = &(nativecomptable[i]); - for (i = 0; i < c->fieldscount; i++) { - /* compare field names */ - if ((c->fields[i].name == name)) - return i; + if (cname == n->classname && mname == n->methodname && + desc == n->descriptor && isstatic == n->isstatic) + return n->func; } - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); + /* no function was found, throw exception */ + + *exceptionptr = + new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError, + mname); - return -1; + return NULL; } +#endif /* defined(WITH_STATIC_CLASSPATH) */ -/********************** function: native_new_and_init ************************* +/* native_make_overloaded_function ********************************************* + + XXX - 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) +static char *native_make_overloaded_function(char *name, utf *desc) { - methodinfo *m; - java_objectheader *o; - - if (!c) - return *exceptionptr; - - o = builtin_new(c); /* create object */ - - if (!o) - return NULL; + 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("()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, NULL, NULL, NULL); + newname[i] = '\0'; - return o; + return newname; } -java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) -{ - methodinfo *m; - java_objectheader *o; +/* native_insert_char ********************************************************** - if (!c) - return *exceptionptr; + Inserts the passed UTF character into the native method name. If + necessary it is escaped properly. - o = builtin_new(c); /* create object */ +*******************************************************************************/ - if (!o) - return NULL; +static s4 native_insert_char(char *name, u4 pos, u2 c) +{ + s4 val; + s4 i; - /* find initializer */ + switch (c) { + case '/': + case '.': + /* replace '/' or '.' with '_' */ + name[pos] = '_'; + break; + + 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; + } - 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); + pos += 4; } - return o; + break; } - /* call initializer */ - - asm_calljavafunction(m, o, s, NULL, NULL); + /* return the new buffer index */ - return o; + return pos; } -java_objectheader *native_new_and_init_int(classinfo *c, s4 i) -{ - methodinfo *m; - java_objectheader *o; +/* native_resolve_function ***************************************************** - if (!c) - return *exceptionptr; + Resolves a native function, maybe from a dynamic library. - o = builtin_new(c); /* create object */ - - if (!o) return NULL; - - /* 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; + u2 c; + u4 pos; + s4 dumpsize; + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ + + /* 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. We multiply the + class and method name length by 6 as this is the maxium + escape-sequence that can be generated (unicode). */ - /* 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) * 6 + + strlen("_") + + utf_get_number_of_u2s(m->name) * 6 + + strlen("0"); - return o; -} + /* allocate memory */ + dumpsize = dump_size(); -java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) -{ - methodinfo *m; - java_objectheader *o; + name = DMNEW(char, namelen); - if (!c) - return *exceptionptr; + /* generate name of native functions */ - o = builtin_new(c); /* create object */ - - if (!o) return NULL; + strcpy(name, "Java_"); + pos = strlen("Java_"); - /* find initializer */ + utf_ptr = m->class->name->text; + utf_endptr = UTF_END(m->class->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; + for (; utf_ptr < utf_endptr; utf_ptr++, pos++) { + c = *utf_ptr; + pos = native_insert_char(name, pos, c); } - /* call initializer */ - - asm_calljavafunction(m, o, t, NULL, NULL); - - return o; -} + /* seperator between class and method */ + name[pos++] = '_'; -/******************** function: stringtable_update **************************** + utf_ptr = m->name->text; + utf_endptr = UTF_END(m->name); - 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 - -*******************************************************************************/ - -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; - } - } + for (; utf_ptr < utf_endptr; utf_ptr++, pos++) { + c = *utf_ptr; + pos = native_insert_char(name, pos, c); } -} - -/************************* function: u2_utflength *************************** + /* close string */ - returns the utf length in bytes of a u2 array + name[pos] = '\0'; -*****************************************************************************/ + /* check for an buffer overflow */ -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; - } - - return result_len; -} + assert(pos <= namelen); + /* generate overloaded function (having the types in it's name) */ -/********************* function: utf_new_u2 *********************************** + newname = native_make_overloaded_function(name, m->descriptor); - make utf symbol from u2 array, - if isclassname is true '.' is replaced by '/' + /* check the library hash entries of the classloader of the + methods's class */ -*******************************************************************************/ + sym = NULL; -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; - } - } - - /* insert utf-string into symbol-table */ - result = utf_new(buffer,buflength); + /* normally addresses are aligned to 4, 8 or 16 bytes */ - MFREE(buffer, char, buflength); + key = ((u4) (ptrint) m->class->classloader) >> 4; /* align to 16-byte */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; - return result; -} + /* iterate through loaders in this hash slot */ + while ((le != NULL) && (sym == NULL)) { + /* iterate through names in this loader */ -/********************* function: javastring_toutf ***************************** + ne = le->namelink; + + while ((ne != NULL) && (sym == NULL)) { + sym = lt_dlsym(ne->handle, name); - make utf symbol from javastring + if (sym == NULL) + sym = lt_dlsym(ne->handle, newname); -*******************************************************************************/ + ne = ne->hashlink; + } -utf *javastring_toutf(java_lang_String *string, bool isclassname) -{ - java_lang_String *str = (java_lang_String *) string; + le = le->hashlink; + } -/* printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count); */ -/* fflush(stdout); */ + if (sym != NULL) + if (opt_verbosejni) + printf("JNI ]\n"); - return utf_new_u2(str->value->data + str->offset, str->count, isclassname); -} + /* If not found, try to find the native function symbol in the + main program. */ -/********************* function: literalstring_u2 ***************************** + if (sym == NULL) { + sym = lt_dlsym(mainhandle, name); - searches for the javastring with the specified u2-array in - the string hashtable, if there is no such string a new one is - created + if (sym == NULL) + sym = lt_dlsym(mainhandle, newname); - if copymode is true a copy of the u2-array is made + if (sym != NULL) + if (opt_verbosejni) + printf("internal ]\n"); + } -*******************************************************************************/ -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); +#if defined(ENABLE_JVMTI) + /* fire Native Method Bind event */ + if (jvmti) jvmti_NativeMethodBind(m, sym, &sym); #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); + /* no symbol found? throw exception */ -#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; - } + if (sym == NULL) { + if (opt_verbosejni) + printf("failed ]\n"); - 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; + exceptions_throw_unsatisfiedlinkerror(m->name); } - /* location in hashtable found, complete arrayheader */ - stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; - stringdata->header.size = length; - - /* 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")); + /* release memory */ - if (!class_load(class_java_lang_String)) - return NULL; - - list_addfirst(&unlinkedclasses, class_java_lang_String); - } - - /* 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; - } + dump_release(dumpsize); - return (java_objectheader *) js; + return (functionptr) (ptrint) sym; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ -/******************** Function: literalstring_new ***************************** - - creates a new javastring with the text of the utf-symbol - and inserts it into the string hashtable +/* 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_objectheader *literalstring_new(utf *u) +java_objectheader *native_new_and_init(classinfo *c) { - 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; - - /* allocate memory */ - a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10); + methodinfo *m; + java_objectheader *o; - /* convert utf-string to u2-array */ - for (i = 0; i < utflength; i++) - a->data[i] = utf_nextu2(&utf_ptr); + if (c == NULL) + vm_abort("native_new_and_init: c == NULL"); - return literalstring_u2(a, utflength, 0, false); -} + /* create object */ + o = builtin_new(c); + + if (o == NULL) + return NULL; -/********************** function: literalstring_free ************************** + /* try to find the initializer */ - removes a javastring from memory + 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 == NULL) + return o; -void literalstring_free(java_objectheader* sobj) -{ - java_lang_String *s = (java_lang_String *) sobj; - java_chararray *a = s->value; + /* call initializer */ - /* dispose memory of java.lang.String object */ - FREE(s, java_lang_String); + (void) vm_call_method(m, o); - /* dispose memory of java-characterarray */ - FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */ + return o; } -void copy_vftbl(vftbl_t **dest, vftbl_t *src) +java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s) { - *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 -} - - -/****************************************************************************************** + methodinfo *m; + java_objectheader *o; - creates method signature (excluding return type) from array of - class-objects representing the parameters of the method + if (c == NULL) + vm_abort("native_new_and_init_string: c == NULL"); -*******************************************************************************************/ + /* create object */ + o = builtin_new(c); -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 */ - } + if (o == NULL) + return NULL; - } else { - /* check for primitive types */ - for (j = 0; j < PRIMITIVETYPE_COUNT; j++) { - char *utf_pos = utf_ptr - 1; - char *primitive = primitivetype_table[j].wrapname; + /* find initializer */ - /* compare text */ - while (utf_pos < utf_end(c->name)) { - if (*utf_pos++ != *primitive++) goto nomatch; - } + m = class_resolveclassmethod(c, + utf_init, + utf_java_lang_String__void, + NULL, + true); - /* primitive type found */ - *pos++ = primitivetype_table[j].typesig; - goto next_type; + /* initializer not found */ - nomatch: - ; - } + if (m == NULL) + return NULL; - /* no primitive type and no arrayclass, so must be object */ - *pos++ = 'L'; + /* call initializer */ - /* copy text */ - for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) { - *pos++ = *utf_ptr; - } + (void) vm_call_method(m, o, s); - *pos++ = ';'; + return o; +} - next_type: - ; - } - } - *pos++ = ')'; +java_objectheader *native_new_and_init_int(classinfo *c, s4 i) +{ + methodinfo *m; + java_objectheader *o; - if (retType) { - for (i = 0; i < strlen(retType); i++) { - *pos++ = retType[i]; - } - } + if (c == NULL) + vm_abort("native_new_and_init_int: c == NULL"); - /* create utf-string */ - result = utf_new(buffer, (pos - buffer)); - MFREE(buffer, char, buffer_size); + /* create object */ - return result; -} + o = builtin_new(c); + + if (o == NULL) + return NULL; + /* find initializer */ -/****************************************************************************************** + m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true); - retrieve the next argument or returntype from a descriptor - and return the corresponding class + /* initializer not found */ -*******************************************************************************************/ + if (m == NULL) + return NULL; -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"); + /* call initializer */ - if (skip) return NULL; + (void) vm_call_method(m, o, i); - use_class_as_object(c); - return c; + return o; } -/* get_parametertypes ********************************************************** - - use the descriptor of a method to generate a java/lang/Class array - which contains the classes of the parametertypes of the method - -*******************************************************************************/ - -java_objectarray* get_parametertypes(methodinfo *m) +java_objectheader *native_new_and_init_throwable(classinfo *c, java_objectheader *t) { - 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; -} + java_objectheader *o; + methodinfo *m; + if (c == NULL) + vm_abort("native_new_and_init_throwable: c == NULL"); -/* get_exceptiontypes ********************************************************** + /* create object */ - get the exceptions which can be thrown by a method + o = builtin_new(c); + + if (o == NULL) + return NULL; -*******************************************************************************/ + /* find initializer */ -java_objectarray* get_exceptiontypes(methodinfo *m) -{ - u2 excount; - u2 i; - java_objectarray *result; + m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void); + + /* initializer not found */ - excount = m->thrownexceptionscount; + if (m == NULL) + return NULL; - /* create class-array */ - result = builtin_anewarray(excount, class_java_lang_Class); + /* call initializer */ - for (i = 0; i < excount; i++) { - java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]); - use_class_as_object((classinfo *) o); - result->data[i] = o; - } + (void) vm_call_method(m, o, t); - return result; + return o; } +/* native_class_getdeclaredannotations ***************************************** + Implementation for + java.lang.Class.getDeclaredAnnotations(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation; +*******************************************************************************/ -/****************************************************************************************** - - get the returntype class of a method - -*******************************************************************************************/ - -classinfo *get_returntype(methodinfo *m) +#if defined(ENABLE_JAVASE) +java_objectarray *native_class_getdeclaredannotations(classinfo *c) { - char *utf_ptr; /* current position in utf-text */ - char *desc_end; /* points behind utf string */ - utf *desc = m->descriptor; /* method-descriptor */ - - utf_ptr = desc->text; - desc_end = utf_end(desc); + java_objectarray *oa; + s4 count; + s4 i; - /* ignore parametertypes */ - while ((utf_ptrruntimevisibleannotationscount; -/*--------------------------------------------------------*/ -void printNativeCall(nativeCall nc) { - int i,j; + oa = builtin_anewarray(count, class_java_lang_annotation_Annotation); - printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout); - for (i=0; iaCalled = %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); -} - -/*--------------------------------------------------------*/ -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); -} + /* fill the annotations */ + for (i = 0; i < count; i++) { + } -/*--------------------------------------------------------*/ -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; + return oa; } +#endif -/*--------------------------------------------------------*/ -nativeCall* findNativeClassCalls(char *aclassname ) { -int i; -for (i=0;iclassname = 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; - } - } - } -} + Use the descriptor of a method to generate a java/lang/Class array + which contains the classes of the parametertypes of the method. +*******************************************************************************/ +java_objectarray *native_get_parametertypes(methodinfo *m) +{ + methoddesc *md; + typedesc *paramtypes; + s4 paramcount; + java_objectarray *oa; + s4 i; -/*--------------------------------------------------------*/ + md = m->parseddesc; -bool natcall2utf(bool natcallcompdone) { -int i; + /* is the descriptor fully parsed? */ -if (natcallcompdone) - return true; + if (!m->parseddesc->params) + if (!descriptor_params_from_paramtypes(md, m->flags)) + return NULL; -for (i=0;iparamtypes; + paramcount = md->paramcount; -return true; -} + /* skip `this' pointer */ -/*--------------------------------------------------------*/ + if (!(m->flags & ACC_STATIC)) { + paramtypes++; + paramcount--; + } + /* create class-array */ -java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start) -{ -#if defined(__GNUC__) -#warning platform dependend -#endif - java_objectarray *tmpArray; - int i; - classinfo **current; - classinfo *c; - size_t size; + oa = builtin_anewarray(paramcount, class_java_lang_Class); - size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*); + if (!oa) + return NULL; - /*printf("end %p, start %p, size %ld\n",end,start,size);*/ - if (!class_java_lang_Class) - class_java_lang_Class = class_new(utf_new_char("java/lang/Class")); + /* get classes */ - if (!class_java_lang_SecurityManager) - class_java_lang_SecurityManager = - class_new(utf_new_char("java/lang/SecurityManager")); + for (i = 0; i < paramcount; i++) + if (!resolve_class_from_typedesc(¶mtypes[i], true, false, + (classinfo **) &oa->data[i])) + return NULL; - if (size > 0) { - if (start == class_java_lang_SecurityManager) { - size--; - start--; - } - } + return oa; +} - tmpArray = - builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl); - 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; - } +/* native_get_exceptiontypes *************************************************** - return tmpArray; -} + Get the exceptions which can be thrown by a method. +*******************************************************************************/ -java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start) +java_objectarray *native_get_exceptiontypes(methodinfo *m) { -#if defined(__GNUC__) -#warning platform dependend -#endif - int i; - classinfo **current; - classinfo *c; - classinfo *privilegedAction; - size_t size; + java_objectarray *oa; + classinfo *c; + u2 i; - size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*); + /* create class-array */ - /* log_text("builtin_asm_getclassloader"); - printf("end %p, start %p, size %ld\n",end,start,size);*/ + oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class); - if (!class_java_lang_SecurityManager) - class_java_lang_SecurityManager = - class_new(utf_new_char("java/lang/SecurityManager")); + if (!oa) + return NULL; - if (size > 0) { - if (start == class_java_lang_SecurityManager) { - size--; - start--; - } + for (i = 0; i < m->thrownexceptionscount; i++) { + if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[i], + resolveEager, true, false, &c)) + return NULL; + + oa->data[i] = (java_objectheader *) c; } - privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction")); + return oa; +} - for(i = 0, current = start; i < size; i++, current--) { - c = *current; - if (c == privilegedAction) - return NULL; +/* native_get_returntype ******************************************************* - if (c->classloader) - return (java_lang_ClassLoader *) c->classloader; - } + Get the returntype class of a method. - return NULL; +*******************************************************************************/ - /* - log_text("Java_java_lang_VMSecurityManager_currentClassLoader"); - init_systemclassloader(); +classinfo *native_get_returntype(methodinfo *m) +{ + classinfo *c; + + if (!resolve_class_from_typedesc(&(m->parseddesc->returntype), true, false, + &c)) + return NULL; - return SystemClassLoader;*/ + return c; }