X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fnative.c;h=a71c7383dcb9aced0ffe47822b26ab0bd54fa61f;hb=a3194739a44a0ac20fdd805e05e7f769786a9c81;hp=40820dc329f4824efd0b6983f40ece52c2c37334;hpb=5b5fca2f4749daae5cd076a3ae8a2fb9a568cf12;p=cacao.git diff --git a/src/native/native.c b/src/native/native.c index 40820dc32..a71c7383d 100644 --- a/src/native/native.c +++ b/src/native/native.c @@ -1,9 +1,9 @@ /* 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,96 +19,364 @@ 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 - - Changes: Christian Thalinger - - $Id: native.c 2193 2005-04-02 19:33:43Z edwin $ + $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 "cacao/cacao.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/stringlocal.h" -#include "vm/tables.h" +#include "vm/vm.h" + #include "vm/jit/asmpart.h" #include "vm/jit/jit.h" -#include "vm/resolve.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 ******************************************/ -#include "nativetable.inc" +#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 +#elif defined(ENABLE_JAVAME_CLDC1_1) -/************* use classinfo structure as java.lang.Class object **************/ +#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" -void use_class_as_object(classinfo *c) -{ - if (!c->classvftbl) { - /* is the class loaded */ - if (!c->loaded) -/* if (!class_load(c)) */ -/* throw_exception_exit(); */ - panic("use_class_as_object: class_load should not happen"); - - /* is the class linked */ - if (!c->linked) - if (!link_class(c)) - throw_exception_exit(); - - /*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");*/ - assert(class_java_lang_Class); - c->header.vftbl = class_java_lang_Class->vftbl; - c->classvftbl = true; - } -} +#endif + +#if defined(WITH_STATIC_CLASSPATH) + +/* these are required to prevent compiler warnings */ + +#include "native/include/java_net_DatagramPacket.h" +#include "native/include/java_net_InetAddress.h" +#include "native/include/java_net_SocketImpl.h" + +#include "native/include/gnu_java_net_PlainDatagramSocketImpl.h" +#include "native/include/gnu_java_net_PlainSocketImpl.h" +#include "native/include/gnu_java_nio_PipeImpl.h" +#include "native/include/gnu_java_nio_channels_FileChannelImpl.h" +#include "native/include/gnu_java_nio_charset_iconv_IconvEncoder.h" +#include "native/include/gnu_java_nio_charset_iconv_IconvDecoder.h" +#include "native/include/java_lang_VMProcess.h" +#include "native/include/java_nio_MappedByteBufferImpl.h" +#include "native/include/java_nio_channels_spi_SelectorProvider.h" + +/* now include the native table */ + +#include "native/nativetable.inc" + +#elif !defined(ENABLE_LIBJVM) + +/* dummynativetable ************************************************************ + + Ensure that symbols for functions implemented within CACAO are used + and exported to dlopen. + + ATTENTION: Don't make this table static!!! Otherwise the compiler + may optimize it away! + +*******************************************************************************/ + +functionptr dummynativetable[] = { +#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 + +#elif defined(ENABLE_JAVAME_CLDC1_1) + (functionptr) Java_com_sun_cldc_io_ResourceInputStream_open, + + (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, + + (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, -/************************** tables for methods ********************************/ + (functionptr) Java_java_lang_Double_doubleToLongBits, -#undef JOWENN_DEBUG -#undef JOWENN_DEBUG1 + (functionptr) Java_java_lang_Float_floatToIntBits, -#ifdef STATIC_CLASSPATH + (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, + + (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, + + (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, + + (functionptr) Java_java_lang_Thread_currentThread, + (functionptr) Java_java_lang_Thread_setPriority0, + (functionptr) Java_java_lang_Thread_start0, + (functionptr) Java_java_lang_Thread_yield, + + (functionptr) Java_java_lang_Throwable_printStackTrace, + (functionptr) Java_java_lang_Throwable_fillInStackTrace +#endif +}; + +#endif /* defined(ENABLE_LIBJVM) */ + + +/* tables for methods *********************************************************/ + +#if defined(WITH_STATIC_CLASSPATH) #define NATIVETABLESIZE (sizeof(nativetable)/sizeof(struct nativeref)) /* table for fast string comparison */ @@ -119,33 +387,48 @@ static bool nativecompdone = false; #endif -/* XXX don't define this in a header file!!! */ - -static struct nativeCall nativeCalls[] = -{ -#include "nativecalls.inc" -}; +/* global variables ***********************************************************/ -#define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall)) - -struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE]; +#if !defined(WITH_STATIC_CLASSPATH) +static hashtable *hashtable_library; +static lt_dlhandle mainhandle; +#endif -/* native_loadclasses ********************************************************** +/* native_init ***************************************************************** - Load classes required for native methods. + Initializes the native subsystem. *******************************************************************************/ bool native_init(void) { -#if !defined(STATIC_CLASSPATH) - void *p; +#if !defined(WITH_STATIC_CLASSPATH) + /* initialize libltdl */ + + if (lt_dlinit()) + vm_abort("native_init: lt_dlinit failed: %s\n", lt_dlerror()); + + /* Get the handle for the main program or for the libjvm.so, + depends on the configuration. */ - /* 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; +# 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); + + hashtable_create(hashtable_library, 10); #endif /* everything's ok */ @@ -154,27 +437,160 @@ bool native_init(void) } -/*********************** Function: native_findfunction ************************* +/* native_hashtable_library_add ************************************************ + + Adds an entry to the native library hashtable. + +*******************************************************************************/ + +#if !defined(WITH_STATIC_CLASSPATH) +void native_hashtable_library_add(utf *filename, java_objectheader *loader, + lt_dlhandle handle) +{ + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ + + LOCK_MONITOR_ENTER(hashtable_library->header); + + /* normally addresses are aligned to 4, 8 or 16 bytes */ + + key = ((u4) (ptrint) loader) >> 4; /* align to 16-byte boundaries */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; + + /* search external hash chain for the entry */ + + while (le) { + if (le->loader == loader) + break; + + le = le->hashlink; /* next element in external chain */ + } + + /* no loader found? create a new entry */ + + if (le == NULL) { + le = NEW(hashtable_library_loader_entry); + + le->loader = loader; + le->namelink = NULL; - 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) + /* insert entry into hashtable */ - Remark: For faster operation, the names/descriptors are converted from C - strings to Unicode the first time this function is called. + le->hashlink = + (hashtable_library_loader_entry *) hashtable_library->ptr[slot]; + hashtable_library->ptr[slot] = le; + + /* update number of hashtable-entries */ + + hashtable_library->entries++; + } + + + /* search for library name */ + + ne = le->namelink; + + while (ne) { + if (ne->name == filename) { + LOCK_MONITOR_EXIT(hashtable_library->header); + + return; + } + + ne = ne->hashlink; /* next element in external chain */ + } + + /* not found? add the library name to the classloader */ + + ne = NEW(hashtable_library_name_entry); + + ne->name = filename; + ne->handle = handle; + + /* insert entry into external chain */ + + ne->hashlink = le->namelink; + le->namelink = ne; + + LOCK_MONITOR_EXIT(hashtable_library->header); +} +#endif /* !defined(WITH_STATIC_CLASSPATH) */ + + +/* native_hashtable_library_find *********************************************** + + Find an entry in the native library hashtable. *******************************************************************************/ -functionptr native_findfunction(utf *cname, utf *mname, - utf *desc, bool isstatic) +#if !defined(WITH_STATIC_CLASSPATH) +hashtable_library_name_entry *native_hashtable_library_find(utf *filename, + java_objectheader *loader) +{ + hashtable_library_loader_entry *le; + hashtable_library_name_entry *ne; /* library name */ + u4 key; /* hashkey */ + u4 slot; /* slot in hashtable */ + + /* normally addresses are aligned to 4, 8 or 16 bytes */ + + key = ((u4) (ptrint) loader) >> 4; /* align to 16-byte boundaries */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; + + /* search external hash chain for the entry */ + + while (le) { + if (le->loader == loader) + break; + + le = le->hashlink; /* next element in external chain */ + } + + /* no loader found? return NULL */ + + if (!le) + return NULL; + + /* search for library name */ + + ne = le->namelink; + + while (ne) { + if (ne->name == filename) + return ne; + + ne = ne->hashlink; /* next element in external chain */ + } + + /* return entry, if no entry was found, ne is NULL */ + + return ne; +} +#endif /* !defined(WITH_STATIC_CLASSPATH) */ + + +/* native_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) + + Remark: For faster operation, the names/descriptors are converted + from C strings to Unicode the first time this function is called. + +*******************************************************************************/ + +#if defined(WITH_STATIC_CLASSPATH) +functionptr native_findfunction(utf *cname, utf *mname, utf *desc, + bool isstatic) { -#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; + s4 i; isstatic = isstatic ? true : false; @@ -182,136 +598,361 @@ functionptr native_findfunction(utf *cname, utf *mname, 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 = + + nativecomptable[i].descriptor = utf_new_char(nativetable[i].descriptor); - nativecomptable[i].isstatic = - nativetable[i].isstatic; - nativecomptable[i].func = - nativetable[i].func; + + 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); - - 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); + } - 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); + /* no function was found, throw exception */ - log_text(buffer); + *exceptionptr = + new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError, + mname); - MFREE(buffer, char, buffer_len); - } - } -#endif - } + return NULL; +} +#endif /* defined(WITH_STATIC_CLASSPATH) */ - - /* no function was found, display warning */ - buffer_len = - utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64; +/* native_make_overloaded_function ********************************************* + + XXX - buffer = MNEW(char, buffer_len); +*******************************************************************************/ - 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 !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); + } + } - log_text(buffer); - MFREE(buffer, char, buffer_len); + /* 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); + } + } -/* exit(1); */ + /* close string */ - /* keep compiler happy */ - return NULL; -#else -/* dynamic classpath */ - return 0; -#endif + newname[i] = '\0'; + + return newname; } -/****************** function class_findfield_approx **************************** - - searches in 'classinfo'-structure for a field with the - specified name +/* native_insert_char ********************************************************** + + Inserts the passed UTF character into the native method name. If + necessary it is escaped properly. *******************************************************************************/ - -fieldinfo *class_findfield_approx(classinfo *c, utf *name) + +static s4 native_insert_char(char *name, u4 pos, u2 c) { + s4 val; s4 i; - for (i = 0; i < c->fieldscount; i++) { - /* compare field names */ - if ((c->fields[i].name == name)) - return &(c->fields[i]); + 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; + } + + pos += 4; + } + break; } - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); + /* return the new buffer index */ - return NULL; + return pos; } -s4 class_findfield_index_approx(classinfo *c, utf *name) +/* native_resolve_function ***************************************************** + + Resolves a native function, maybe from a dynamic library. + +*******************************************************************************/ + +functionptr native_resolve_function(methodinfo *m) { - s4 i; + 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). */ + + namelen = strlen("Java_") + + utf_get_number_of_u2s(m->class->name) * 6 + + strlen("_") + + utf_get_number_of_u2s(m->name) * 6 + + strlen("0"); + + /* allocate memory */ + + dumpsize = dump_size(); + + name = DMNEW(char, namelen); + + /* generate name of native functions */ + + strcpy(name, "Java_"); + pos = strlen("Java_"); + + utf_ptr = m->class->name->text; + utf_endptr = UTF_END(m->class->name); + + for (; utf_ptr < utf_endptr; utf_ptr++, pos++) { + c = *utf_ptr; + pos = native_insert_char(name, pos, c); + } + + /* seperator between class and method */ + + name[pos++] = '_'; + + utf_ptr = m->name->text; + utf_endptr = UTF_END(m->name); + + for (; utf_ptr < utf_endptr; utf_ptr++, pos++) { + c = *utf_ptr; + pos = native_insert_char(name, pos, c); + } + + /* close string */ + + name[pos] = '\0'; + + /* check for an buffer overflow */ + + assert(pos <= namelen); + + /* generate overloaded function (having the types in it's name) */ + + newname = native_make_overloaded_function(name, m->descriptor); + + /* check the library hash entries of the classloader of the + methods's class */ + + sym = NULL; + + /* normally addresses are aligned to 4, 8 or 16 bytes */ - for (i = 0; i < c->fieldscount; i++) { - /* compare field names */ - if ((c->fields[i].name == name)) - return i; + key = ((u4) (ptrint) m->class->classloader) >> 4; /* align to 16-byte */ + slot = key & (hashtable_library->size - 1); + le = hashtable_library->ptr[slot]; + + /* iterate through loaders in this hash slot */ + + while ((le != NULL) && (sym == NULL)) { + /* iterate through names in this loader */ + + ne = le->namelink; + + while ((ne != NULL) && (sym == NULL)) { + sym = lt_dlsym(ne->handle, name); + + if (sym == NULL) + sym = lt_dlsym(ne->handle, newname); + + ne = ne->hashlink; + } + + le = le->hashlink; + } + + if (sym != NULL) + if (opt_verbosejni) + printf("JNI ]\n"); + + + /* If not found, try to find the native function symbol in the + main program. */ + + if (sym == NULL) { + sym = lt_dlsym(mainhandle, name); + + if (sym == NULL) + sym = lt_dlsym(mainhandle, newname); + + if (sym != NULL) + if (opt_verbosejni) + printf("internal ]\n"); + } + + +#if defined(ENABLE_JVMTI) + /* fire Native Method Bind event */ + if (jvmti) jvmti_NativeMethodBind(m, sym, &sym); +#endif + + /* no symbol found? throw exception */ + + if (sym == NULL) { + if (opt_verbosejni) + printf("failed ]\n"); + + exceptions_throw_unsatisfiedlinkerror(m->name); } - /* field was not found, raise exception */ - *exceptionptr = new_exception(string_java_lang_NoSuchFieldException); + /* release memory */ - return -1; + dump_release(dumpsize); + + return (functionptr) (ptrint) sym; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ /* native_new_and_init ********************************************************* @@ -326,46 +967,47 @@ java_objectheader *native_new_and_init(classinfo *c) methodinfo *m; java_objectheader *o; - if (!c) - return *exceptionptr; + if (c == NULL) + vm_abort("native_new_and_init: c == NULL"); /* create object */ o = builtin_new(c); - if (!o) + if (o == NULL) return NULL; - /* find initializer */ + /* try to find the initializer */ m = class_findmethod(c, utf_init, utf_void__void); - /* initializer not found */ + /* ATTENTION: returning the object here is ok, since the class may + not have an initializer */ - if (!m) + if (m == NULL) return o; /* call initializer */ - asm_calljavafunction(m, o, NULL, NULL, NULL); + (void) vm_call_method(m, o); return o; } -java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) +java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s) { - methodinfo *m; + methodinfo *m; java_objectheader *o; - if (!c) - return *exceptionptr; + if (c == NULL) + vm_abort("native_new_and_init_string: c == NULL"); /* create object */ o = builtin_new(c); - if (!o) + if (o == NULL) return NULL; /* find initializer */ @@ -378,12 +1020,12 @@ java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) /* initializer not found */ - if (!m) + if (m == NULL) return NULL; /* call initializer */ - asm_calljavafunction(m, o, s, NULL, NULL); + (void) vm_call_method(m, o, s); return o; } @@ -394,14 +1036,14 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i) methodinfo *m; java_objectheader *o; - if (!c) - return *exceptionptr; + if (c == NULL) + vm_abort("native_new_and_init_int: c == NULL"); /* create object */ o = builtin_new(c); - if (!o) + if (o == NULL) return NULL; /* find initializer */ @@ -410,30 +1052,30 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i) /* initializer not found */ - if (!m) + if (m == NULL) return NULL; /* call initializer */ - asm_calljavafunction(m, o, (void *) (ptrint) i, NULL, NULL); + (void) vm_call_method(m, o, i); return o; } -java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) +java_objectheader *native_new_and_init_throwable(classinfo *c, java_objectheader *t) { - methodinfo *m; java_objectheader *o; + methodinfo *m; - if (!c) - return *exceptionptr; + if (c == NULL) + vm_abort("native_new_and_init_throwable: c == NULL"); /* create object */ o = builtin_new(c); - if (!o) + if (o == NULL) return NULL; /* find initializer */ @@ -442,417 +1084,154 @@ java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwab /* initializer not found */ - if (!m) + if (m == NULL) return NULL; /* call initializer */ - asm_calljavafunction(m, o, t, NULL, NULL); + (void) vm_call_method(m, o, t); return o; } -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 -} - - -/****************************************************************************************** +/* native_class_getdeclaredannotations ***************************************** - creates method signature (excluding return type) from array of - class-objects representing the parameters of the method - -*******************************************************************************************/ + Implementation for + java.lang.Class.getDeclaredAnnotations(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation; +*******************************************************************************/ -utf *create_methodsig(java_objectarray* types, char *retType) +#if defined(ENABLE_JAVASE) +java_objectarray *native_class_getdeclaredannotations(classinfo *c) { - 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; + java_objectarray *oa; + s4 count; + s4 i; - /* compare text */ - while (utf_pos < utf_end(c->name)) { - if (*utf_pos++ != *primitive++) goto nomatch; - } + classinfo *class_java_lang_annotation_Annotation; - /* 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); - - return result; -} + /* create Annotation-array */ + /* XXX should we cache that class? */ + if (!(class_java_lang_annotation_Annotation = + load_class_bootstrap(utf_new_char("java/lang/annotation/Annotation")))) + return NULL; -/* get_parametertypes ********************************************************** + count = c->runtimevisibleannotationscount; - use the descriptor of a method to generate a java/lang/Class array - which contains the classes of the parametertypes of the method + oa = builtin_anewarray(count, class_java_lang_annotation_Annotation); -*******************************************************************************/ - -java_objectarray* get_parametertypes(methodinfo *m) -{ - methoddesc *descr = m->parseddesc; /* method-descriptor */ - java_objectarray* result; - int parametercount = descr->paramcount; - int i; + if (oa == NULL) + return NULL; - /* create class-array */ - assert(class_java_lang_Class); - result = builtin_anewarray(parametercount, class_java_lang_Class); + /* fill the annotations */ - /* get classes */ - for (i = 0; i < parametercount; i++) { - if (!resolve_class_from_typedesc(descr->paramtypes + i,false, - (classinfo **) (result->data + i))) - return NULL; /* exception */ - use_class_as_object((classinfo*) result->data[i]); + for (i = 0; i < count; i++) { } - return result; + return oa; } +#endif -/* get_exceptiontypes ********************************************************** +/* native_get_parametertypes *************************************************** - get the exceptions which can be thrown by a method + 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_exceptiontypes(methodinfo *m) -{ - u2 excount; - u2 i; - java_objectarray *result; - classinfo *cls; - - excount = m->thrownexceptionscount; - - /* create class-array */ - assert(class_java_lang_Class); - result = builtin_anewarray(excount, class_java_lang_Class); - - for (i = 0; i < excount; i++) { - if (!resolve_classref_or_classinfo(NULL,m->thrownexceptions[i],resolveEager,false,&cls)) - return NULL; /* exception */ - use_class_as_object(cls); - result->data[i] = (java_objectheader *)cls; - } - - return result; -} - - -/****************************************************************************************** - - get the returntype class of a method - -*******************************************************************************************/ - -classinfo *get_returntype(methodinfo *m) +java_objectarray *native_get_parametertypes(methodinfo *m) { - classinfo *cls; + methoddesc *md; + typedesc *paramtypes; + s4 paramcount; + java_objectarray *oa; + s4 i; - if (!resolve_class_from_typedesc(&(m->parseddesc->returntype),false,&cls)) - return NULL; /* exception */ + md = m->parseddesc; - use_class_as_object(cls); - return cls; -} - - -/*****************************************************************************/ -/*****************************************************************************/ + /* is the descriptor fully parsed? */ + if (!m->parseddesc->params) + if (!descriptor_params_from_paramtypes(md, m->flags)) + return NULL; -/*--------------------------------------------------------*/ -void printNativeCall(nativeCall nc) { - int i,j; + paramtypes = md->paramtypes; + paramcount = md->paramcount; - 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); -} + if (!(m->flags & ACC_STATIC)) { + paramtypes++; + paramcount--; + } -/*--------------------------------------------------------*/ -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); -} + /* create class-array */ + oa = builtin_anewarray(paramcount, class_java_lang_Class); -/*--------------------------------------------------------*/ -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; -} + if (!oa) + return NULL; -/*--------------------------------------------------------*/ -nativeCall* findNativeClassCalls(char *aclassname ) { -int i; + /* get classes */ -for (i=0;idata[i])) + return NULL; -return NULL; + return oa; } -/*--------------------------------------------------------*/ -/*--------------------------------------------------------*/ -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; - } - } - } -} - -/*--------------------------------------------------------*/ +/* native_get_exceptiontypes *************************************************** -bool natcall2utf(bool natcallcompdone) { -int i; - -if (natcallcompdone) - return true; - -for (i=0;ithrownexceptionscount, class_java_lang_Class); - if (!class_java_lang_SecurityManager) - if (!load_class_bootstrap(utf_new_char("java/lang/SecurityManager"),&class_java_lang_SecurityManager)) - return NULL; - - if (size > 0) { - if (*start == class_java_lang_SecurityManager) { - size--; - start--; - } - } + if (!oa) + return NULL; - tmpArray = (java_objectarray*) - 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; +/* native_get_returntype ******************************************************* - size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*); + Get the returntype class of a method. - /* log_text("builtin_asm_getclassloader"); - printf("end %p, start %p, size %ld\n",end,start,size);*/ - - if (!class_java_lang_SecurityManager) - if (!load_class_bootstrap(utf_new_char("java/lang/SecurityManager"),&class_java_lang_SecurityManager)) - return NULL; +*******************************************************************************/ - if (size > 0) { - if (*start == class_java_lang_SecurityManager) { - size--; - start--; - } - } +classinfo *native_get_returntype(methodinfo *m) +{ + classinfo *c; - if (!load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"),&privilegedAction)) + if (!resolve_class_from_typedesc(&(m->parseddesc->returntype), true, false, + &c)) return NULL; - for(i = 0, current = start; i < size; i++, current--) { - c = *current; - - if (c == privilegedAction) - return NULL; - - if (c->classloader) - return (java_lang_ClassLoader *) c->classloader; - } - - return NULL; + return c; }