Merged revisions 7642-7664 via svnmerge from
[cacao.git] / src / native / native.c
1 /* src/native/native.c - table of native functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: native.c 7667 2007-04-05 00:16:05Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <ctype.h>
34
35 #if !defined(WITH_STATIC_CLASSPATH)
36 # include <ltdl.h>
37 #endif
38
39 #include "vm/types.h"
40
41 #include "mm/memory.h"
42 #include "native/jni.h"
43 #include "native/native.h"
44 #include "native/include/java_lang_String.h"
45 #include "native/include/java_lang_Throwable.h"
46
47 #if defined(ENABLE_THREADS)
48 # include "threads/native/lock.h"
49 #else
50 # include "threads/none/lock.h"
51 #endif
52
53 #include "toolbox/hashtable.h"
54 #include "toolbox/logging.h"
55
56 #include "vm/builtin.h"
57 #include "vm/exceptions.h"
58 #include "vm/global.h"
59 #include "vm/stringlocal.h"
60 #include "vm/vm.h"
61
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/jit.h"
64
65 #include "vmcore/loader.h"
66 #include "vmcore/options.h"
67 #include "vm/resolve.h"
68
69 #if defined(ENABLE_JVMTI)
70 #include "native/jvmti/cacaodbg.h"
71 #endif
72
73
74 /* include table of native functions ******************************************/
75
76 #if defined(ENABLE_JAVASE)
77
78 #include "native/include/java_io_InputStream.h"
79 #include "native/include/java_io_PrintStream.h"
80
81 #include "native/include/java_lang_Cloneable.h"
82 #include "native/include/java_util_Properties.h"
83
84 #include "native/include/java_lang_Object.h"
85
86 #include "native/include/gnu_classpath_VMStackWalker.h"
87 #include "native/include/gnu_classpath_VMSystemProperties.h"
88 #include "native/include/gnu_java_lang_management_VMClassLoadingMXBeanImpl.h"
89 #include "native/include/gnu_java_lang_management_VMMemoryMXBeanImpl.h"
90 #include "native/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
91 #include "native/include/java_lang_VMClass.h"
92 #include "native/include/java_security_ProtectionDomain.h"  /* required by... */
93 #include "native/include/java_lang_VMClassLoader.h"
94 #include "native/include/java_lang_VMObject.h"
95 #include "native/include/java_lang_VMRuntime.h"
96 #include "native/include/java_lang_VMString.h"
97 #include "native/include/java_lang_VMSystem.h"
98 #include "native/include/java_lang_VMThread.h"
99 #include "native/include/java_lang_VMThrowable.h"
100 #include "native/include/java_lang_management_VMManagementFactory.h"
101 #include "native/include/java_lang_reflect_Constructor.h"
102 #include "native/include/java_lang_reflect_Field.h"
103 #include "native/include/java_lang_reflect_Method.h"
104 #include "native/include/java_lang_reflect_VMProxy.h"
105 #include "native/include/java_security_VMAccessController.h"
106 #include "native/include/sun_misc_Unsafe.h"
107
108 #if defined(ENABLE_JVMTI)
109 #include "native/include/gnu_classpath_jdwp_event_EventRequest.h"
110 #include "native/include/java_nio_ByteBuffer.h"
111 #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
112 #include "native/include/gnu_classpath_jdwp_VMFrame.h"
113 #include "native/include/gnu_classpath_jdwp_VMMethod.h"
114 #endif
115
116 #elif defined(ENABLE_JAVAME_CLDC1_1)
117
118 #include "native/include/com_sun_cldchi_io_ConsoleOutputStream.h"
119 #include "native/include/java_lang_Class.h"
120 #include "native/include/java_lang_Double.h"
121 #include "native/include/java_lang_Float.h"
122 #include "native/include/java_lang_Math.h"
123 #include "native/include/java_lang_Runtime.h"
124 #include "native/include/java_lang_System.h"
125 #include "native/include/java_lang_Thread.h"
126
127 #endif
128
129 #if defined(WITH_STATIC_CLASSPATH)
130
131 /* these are required to prevent compiler warnings */
132
133 #include "native/include/java_net_DatagramPacket.h"
134 #include "native/include/java_net_InetAddress.h"
135 #include "native/include/java_net_SocketImpl.h"
136
137 #include "native/include/gnu_java_net_PlainDatagramSocketImpl.h"
138 #include "native/include/gnu_java_net_PlainSocketImpl.h"
139 #include "native/include/gnu_java_nio_PipeImpl.h"
140 #include "native/include/gnu_java_nio_channels_FileChannelImpl.h"
141 #include "native/include/gnu_java_nio_charset_iconv_IconvEncoder.h"
142 #include "native/include/gnu_java_nio_charset_iconv_IconvDecoder.h"
143 #include "native/include/java_lang_VMProcess.h"
144 #include "native/include/java_nio_MappedByteBufferImpl.h"
145 #include "native/include/java_nio_channels_spi_SelectorProvider.h"
146
147 /* now include the native table */
148
149 #include "native/nativetable.inc"
150
151 #elif !defined(ENABLE_LIBJVM)
152
153 /* dummynativetable ************************************************************
154
155    Ensure that symbols for functions implemented within CACAO are used
156    and exported to dlopen.
157
158    ATTENTION: Don't make this table static!!!  Otherwise the compiler
159    may optimize it away!
160
161 *******************************************************************************/
162
163 functionptr dummynativetable[] = {
164 #if defined(ENABLE_JAVASE)
165         (functionptr) Java_gnu_classpath_VMStackWalker_getClassContext,
166         (functionptr) Java_gnu_classpath_VMStackWalker_getCallingClass,
167         (functionptr) Java_gnu_classpath_VMStackWalker_getCallingClassLoader,
168         (functionptr) Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader,
169
170         (functionptr) Java_gnu_classpath_VMSystemProperties_preInit,
171
172         (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount,
173         (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount,
174         (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose,
175         (functionptr) Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose,
176
177         (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage,
178         (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage,
179         (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount,
180         (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose,
181         (functionptr) Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose,
182
183         (functionptr) Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments,
184         (functionptr) Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime,
185
186         (functionptr) Java_java_lang_VMClass_isInstance,
187         (functionptr) Java_java_lang_VMClass_isAssignableFrom,
188         (functionptr) Java_java_lang_VMClass_isInterface,
189         (functionptr) Java_java_lang_VMClass_isPrimitive,
190         (functionptr) Java_java_lang_VMClass_getName,
191         (functionptr) Java_java_lang_VMClass_getSuperclass,
192         (functionptr) Java_java_lang_VMClass_getInterfaces,
193         (functionptr) Java_java_lang_VMClass_getComponentType,
194         (functionptr) Java_java_lang_VMClass_getModifiers,
195         (functionptr) Java_java_lang_VMClass_getDeclaringClass,
196         (functionptr) Java_java_lang_VMClass_getDeclaredClasses,
197         (functionptr) Java_java_lang_VMClass_getDeclaredFields,
198         (functionptr) Java_java_lang_VMClass_getDeclaredMethods,
199         (functionptr) Java_java_lang_VMClass_getDeclaredConstructors,
200         (functionptr) Java_java_lang_VMClass_getClassLoader,
201         (functionptr) Java_java_lang_VMClass_forName,
202         (functionptr) Java_java_lang_VMClass_isArray,
203         (functionptr) Java_java_lang_VMClass_throwException,
204
205         (functionptr) Java_java_lang_VMClassLoader_defineClass,
206         (functionptr) Java_java_lang_VMClassLoader_resolveClass,
207         (functionptr) Java_java_lang_VMClassLoader_loadClass,
208         (functionptr) Java_java_lang_VMClassLoader_getPrimitiveClass,
209         (functionptr) Java_java_lang_VMClassLoader_nativeGetResources,
210         (functionptr) Java_java_lang_VMClassLoader_findLoadedClass,
211
212         (functionptr) Java_java_lang_VMObject_getClass,
213         (functionptr) Java_java_lang_VMObject_clone,
214         (functionptr) Java_java_lang_VMObject_notify,
215         (functionptr) Java_java_lang_VMObject_notifyAll,
216         (functionptr) Java_java_lang_VMObject_wait,
217
218         (functionptr) Java_java_lang_VMRuntime_availableProcessors,
219         (functionptr) Java_java_lang_VMRuntime_freeMemory,
220         (functionptr) Java_java_lang_VMRuntime_totalMemory,
221         (functionptr) Java_java_lang_VMRuntime_maxMemory,
222         (functionptr) Java_java_lang_VMRuntime_gc,
223         (functionptr) Java_java_lang_VMRuntime_runFinalization,
224         (functionptr) Java_java_lang_VMRuntime_runFinalizationForExit,
225         (functionptr) Java_java_lang_VMRuntime_traceInstructions,
226         (functionptr) Java_java_lang_VMRuntime_traceMethodCalls,
227         (functionptr) Java_java_lang_VMRuntime_runFinalizersOnExit,
228         (functionptr) Java_java_lang_VMRuntime_exit,
229         (functionptr) Java_java_lang_VMRuntime_nativeLoad,
230         (functionptr) Java_java_lang_VMRuntime_mapLibraryName,
231
232         (functionptr) Java_java_lang_VMString_intern,
233
234         (functionptr) Java_java_lang_VMSystem_arraycopy,
235         (functionptr) Java_java_lang_VMSystem_identityHashCode,
236
237         (functionptr) Java_java_lang_VMThread_start,
238         (functionptr) Java_java_lang_VMThread_interrupt,
239         (functionptr) Java_java_lang_VMThread_isInterrupted,
240         (functionptr) Java_java_lang_VMThread_suspend,
241         (functionptr) Java_java_lang_VMThread_resume,
242         (functionptr) Java_java_lang_VMThread_nativeSetPriority,
243         (functionptr) Java_java_lang_VMThread_nativeStop,
244         (functionptr) Java_java_lang_VMThread_currentThread,
245         (functionptr) Java_java_lang_VMThread_yield,
246         (functionptr) Java_java_lang_VMThread_interrupted,
247         (functionptr) Java_java_lang_VMThread_holdsLock,
248
249         (functionptr) Java_java_lang_VMThrowable_fillInStackTrace,
250         (functionptr) Java_java_lang_VMThrowable_getStackTrace,
251
252         (functionptr) Java_java_lang_management_VMManagementFactory_getMemoryPoolNames,
253         (functionptr) Java_java_lang_management_VMManagementFactory_getMemoryManagerNames,
254         (functionptr) Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames,
255
256         (functionptr) Java_java_lang_reflect_Constructor_getModifiersInternal,
257         (functionptr) Java_java_lang_reflect_Constructor_constructNative,
258
259         (functionptr) Java_java_lang_reflect_Field_getModifiersInternal,
260         (functionptr) Java_java_lang_reflect_Field_getType,
261         (functionptr) Java_java_lang_reflect_Field_get,
262         (functionptr) Java_java_lang_reflect_Field_getBoolean,
263         (functionptr) Java_java_lang_reflect_Field_getByte,
264         (functionptr) Java_java_lang_reflect_Field_getChar,
265         (functionptr) Java_java_lang_reflect_Field_getShort,
266         (functionptr) Java_java_lang_reflect_Field_getInt,
267         (functionptr) Java_java_lang_reflect_Field_getLong,
268         (functionptr) Java_java_lang_reflect_Field_getFloat,
269         (functionptr) Java_java_lang_reflect_Field_getDouble,
270         (functionptr) Java_java_lang_reflect_Field_set,
271         (functionptr) Java_java_lang_reflect_Field_setBoolean,
272         (functionptr) Java_java_lang_reflect_Field_setByte,
273         (functionptr) Java_java_lang_reflect_Field_setChar,
274         (functionptr) Java_java_lang_reflect_Field_setShort,
275         (functionptr) Java_java_lang_reflect_Field_setInt,
276         (functionptr) Java_java_lang_reflect_Field_setLong,
277         (functionptr) Java_java_lang_reflect_Field_setFloat,
278         (functionptr) Java_java_lang_reflect_Field_setDouble,
279
280         (functionptr) Java_java_lang_reflect_Method_getModifiersInternal,
281         (functionptr) Java_java_lang_reflect_Method_getReturnType,
282         (functionptr) Java_java_lang_reflect_Method_getParameterTypes,
283         (functionptr) Java_java_lang_reflect_Method_getExceptionTypes,
284         (functionptr) Java_java_lang_reflect_Method_invokeNative,
285
286         (functionptr) Java_java_lang_reflect_VMProxy_getProxyClass,
287         (functionptr) Java_java_lang_reflect_VMProxy_getProxyData,
288         (functionptr) Java_java_lang_reflect_VMProxy_generateProxyClass,
289
290         (functionptr) Java_java_security_VMAccessController_getStack,
291
292         (functionptr) Java_sun_misc_Unsafe_objectFieldOffset,
293         (functionptr) Java_sun_misc_Unsafe_compareAndSwapInt,
294
295 #if defined(ENABLE_JVMTI)
296         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread,
297         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread,
298         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount,
299         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount,
300         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus,
301         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods,
302         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod,
303         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames,
304         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrame,
305         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount,
306         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus,
307         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests,
308         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod,
309         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile,
310         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent,
311         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent,
312         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents,
313         (functionptr) Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses,
314         (functionptr) Java_gnu_classpath_jdwp_VMFrame_setValue,
315         (functionptr) Java_gnu_classpath_jdwp_VMFrame_getValue,
316         (functionptr) Java_gnu_classpath_jdwp_VMMethod_getName,
317         (functionptr) Java_gnu_classpath_jdwp_VMMethod_getSignature,
318         (functionptr) Java_gnu_classpath_jdwp_VMMethod_getModifiers,
319         (functionptr) Java_gnu_classpath_jdwp_VMMethod_getLineTable,
320         (functionptr) Java_gnu_classpath_jdwp_VMMethod_getVariableTable
321 #endif
322
323 #elif defined(ENABLE_JAVAME_CLDC1_1)
324         (functionptr) Java_com_sun_cldc_io_ResourceInputStream_open,
325
326         (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_open0,
327         (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf,
328         (functionptr) Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte,
329
330         (functionptr) Java_com_sun_cldchi_io_ConsoleOutputStream_write,
331
332         (functionptr) Java_java_lang_Class_forName,
333         (functionptr) Java_java_lang_Class_newInstance,
334         (functionptr) Java_java_lang_Class_isInstance,
335         (functionptr) Java_java_lang_Class_isAssignableFrom,
336         (functionptr) Java_java_lang_Class_isInterface,
337         (functionptr) Java_java_lang_Class_isArray,
338         (functionptr) Java_java_lang_Class_getName,
339
340         (functionptr) Java_java_lang_Double_doubleToLongBits,
341
342         (functionptr) Java_java_lang_Float_floatToIntBits,
343
344         (functionptr) Java_java_lang_Math_ceil,
345         (functionptr) Java_java_lang_Math_cos,
346         (functionptr) Java_java_lang_Math_floor,
347         (functionptr) Java_java_lang_Math_sin,
348         (functionptr) Java_java_lang_Math_sqrt,
349         (functionptr) Java_java_lang_Math_tan,
350
351         (functionptr) Java_java_lang_Object_hashCode,
352         (functionptr) Java_java_lang_Object_notify,
353         (functionptr) Java_java_lang_Object_wait,
354
355         (functionptr) Java_java_lang_Runtime_exitInternal,
356         (functionptr) Java_java_lang_Runtime_freeMemory,
357         (functionptr) Java_java_lang_Runtime_totalMemory,
358         (functionptr) Java_java_lang_Runtime_gc,
359
360         (functionptr) Java_java_lang_String_hashCode,
361         (functionptr) Java_java_lang_String_indexOf__I,
362         (functionptr) Java_java_lang_String_indexOf__II,
363         (functionptr) Java_java_lang_String_lastIndexOf__II,
364         (functionptr) Java_java_lang_String_intern,
365
366         (functionptr) Java_java_lang_System_getProperty0,
367
368         (functionptr) Java_java_lang_Thread_currentThread,
369         (functionptr) Java_java_lang_Thread_setPriority0,
370         (functionptr) Java_java_lang_Thread_start0,
371         (functionptr) Java_java_lang_Thread_yield,
372
373         (functionptr) Java_java_lang_Throwable_printStackTrace,
374         (functionptr) Java_java_lang_Throwable_fillInStackTrace
375 #endif
376 };
377
378 #endif /* defined(ENABLE_LIBJVM) */
379
380
381 /* tables for methods *********************************************************/
382
383 #if defined(WITH_STATIC_CLASSPATH)
384 #define NATIVETABLESIZE  (sizeof(nativetable)/sizeof(struct nativeref))
385
386 /* table for fast string comparison */
387 static nativecompref nativecomptable[NATIVETABLESIZE];
388
389 /* string comparsion table initialized */
390 static bool nativecompdone = false;
391 #endif
392
393
394 /* global variables ***********************************************************/
395
396 #if !defined(WITH_STATIC_CLASSPATH)
397 static hashtable *hashtable_library;
398 static lt_dlhandle mainhandle;
399 #endif
400
401
402 /* native_init *****************************************************************
403
404    Initializes the native subsystem.
405
406 *******************************************************************************/
407
408 bool native_init(void)
409 {
410 #if !defined(WITH_STATIC_CLASSPATH)
411         /* initialize libltdl */
412
413         if (lt_dlinit())
414                 vm_abort("native_init: lt_dlinit failed: %s\n", lt_dlerror());
415
416         /* Get the handle for the main program or for the libjvm.so,
417            depends on the configuration. */
418
419 # if defined(ENABLE_LIBJVM)
420         /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
421            If not found, try the absolute path. */
422
423         if (!(mainhandle = lt_dlopenext("libjvm")))
424                 if (!(mainhandle = lt_dlopenext(cacao_libjvm)))
425                         vm_abort("native_init: lt_dlopenext failed: %s\n", lt_dlerror());
426 # else
427         if (!(mainhandle = lt_dlopen(NULL)))
428                 vm_abort("native_init: lt_dlopen failed: %s\n", lt_dlerror());
429 # endif
430
431         /* initialize library hashtable, 10 entries should be enough */
432
433         hashtable_library = NEW(hashtable);
434
435         hashtable_create(hashtable_library, 10);
436 #endif
437
438         /* everything's ok */
439
440         return true;
441 }
442
443
444 /* native_hashtable_library_add ************************************************
445
446    Adds an entry to the native library hashtable.
447
448 *******************************************************************************/
449
450 #if !defined(WITH_STATIC_CLASSPATH)
451 void native_hashtable_library_add(utf *filename, java_objectheader *loader,
452                                                                   lt_dlhandle handle)
453 {
454         hashtable_classloader_entry    *cle;
455         hashtable_library_loader_entry *le;
456         hashtable_library_name_entry   *ne; /* library name                       */
457         u4   key;                           /* hashkey                            */
458         u4   slot;                          /* slot in hashtable                  */
459
460         LOCK_MONITOR_ENTER(hashtable_library->header);
461
462         /* insert loader into the classloader hashtable */
463
464         cle = loader_hashtable_classloader_add(loader);
465
466         /* normally addresses are aligned to 4, 8 or 16 bytes */
467
468         key  = ((u4) (ptrint) cle) >> 4;        /* align to 16-byte boundaries    */
469         slot = key & (hashtable_library->size - 1);
470         le   = hashtable_library->ptr[slot];
471
472         /* search external hash chain for the entry */
473
474         while (le) {
475                 if (le->cle == cle)
476                         break;
477
478                 le = le->hashlink;                  /* next element in external chain */
479         }
480
481         /* no loader found? create a new entry */
482
483         if (le == NULL) {
484                 le = NEW(hashtable_library_loader_entry);
485
486                 le->cle   = cle;
487                 le->namelink = NULL;
488
489                 /* insert entry into hashtable */
490
491                 le->hashlink =
492                         (hashtable_library_loader_entry *) hashtable_library->ptr[slot];
493                 hashtable_library->ptr[slot] = le;
494
495                 /* update number of hashtable-entries */
496
497                 hashtable_library->entries++;
498         }
499
500
501         /* search for library name */
502
503         ne = le->namelink;
504
505         while (ne) {
506                 if (ne->name == filename) {
507                         LOCK_MONITOR_EXIT(hashtable_library->header);
508
509                         return;
510                 }
511
512                 ne = ne->hashlink;                  /* next element in external chain */
513         }
514
515         /* not found? add the library name to the classloader */
516
517         ne = NEW(hashtable_library_name_entry);
518
519         ne->name   = filename;
520         ne->handle = handle;
521
522         /* insert entry into external chain */
523
524         ne->hashlink = le->namelink;
525         le->namelink = ne;
526
527         LOCK_MONITOR_EXIT(hashtable_library->header);
528 }
529 #endif /* !defined(WITH_STATIC_CLASSPATH) */
530
531
532 /* native_hashtable_library_find ***********************************************
533
534    Find an entry in the native library hashtable.
535
536 *******************************************************************************/
537
538 #if !defined(WITH_STATIC_CLASSPATH)
539 hashtable_library_name_entry *native_hashtable_library_find(utf *filename,
540                                                                                                                         java_objectheader *loader)
541 {
542         hashtable_classloader_entry    *cle;
543         hashtable_library_loader_entry *le;
544         hashtable_library_name_entry   *ne; /* library name                       */
545         u4   key;                           /* hashkey                            */
546         u4   slot;                          /* slot in hashtable                  */
547
548         /* search loader in the classloader hashtable */
549
550         cle = loader_hashtable_classloader_find(loader);
551
552         if (!cle)
553                 return NULL;
554
555         /* normally addresses are aligned to 4, 8 or 16 bytes */
556
557         key  = ((u4) (ptrint) cle) >> 4;        /* align to 16-byte boundaries    */
558         slot = key & (hashtable_library->size - 1);
559         le   = hashtable_library->ptr[slot];
560
561         /* search external hash chain for the entry */
562
563         while (le) {
564                 if (le->cle == cle)
565                         break;
566
567                 le = le->hashlink;                  /* next element in external chain */
568         }
569
570         /* no loader found? return NULL */
571
572         if (!le)
573                 return NULL;
574
575         /* search for library name */
576
577         ne = le->namelink;
578
579         while (ne) {
580                 if (ne->name == filename)
581                         return ne;
582
583                 ne = ne->hashlink;                  /* next element in external chain */
584         }
585
586         /* return entry, if no entry was found, ne is NULL */
587
588         return ne;
589 }
590 #endif /* !defined(WITH_STATIC_CLASSPATH) */
591
592
593 /* native_findfunction *********************************************************
594
595    Looks up a method (must have the same class name, method name,
596    descriptor and 'static'ness) and returns a function pointer to it.
597    Returns: function pointer or NULL (if there is no such method)
598
599    Remark: For faster operation, the names/descriptors are converted
600    from C strings to Unicode the first time this function is called.
601
602 *******************************************************************************/
603
604 #if defined(WITH_STATIC_CLASSPATH)
605 functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
606                                                                 bool isstatic)
607 {
608         /* entry of table for fast string comparison */
609         struct nativecompref *n;
610         s4 i;
611
612         isstatic = isstatic ? true : false;
613         
614         if (!nativecompdone) {
615                 for (i = 0; i < NATIVETABLESIZE; i++) {
616                         nativecomptable[i].classname  = 
617                                 utf_new_char(nativetable[i].classname);
618
619                         nativecomptable[i].methodname = 
620                                 utf_new_char(nativetable[i].methodname);
621
622                         nativecomptable[i].descriptor =
623                                 utf_new_char(nativetable[i].descriptor);
624
625                         nativecomptable[i].isstatic   = nativetable[i].isstatic;
626                         nativecomptable[i].func       = nativetable[i].func;
627                 }
628
629                 nativecompdone = true;
630         }
631
632         for (i = 0; i < NATIVETABLESIZE; i++) {
633                 n = &(nativecomptable[i]);
634
635                 if (cname == n->classname && mname == n->methodname &&
636                     desc == n->descriptor && isstatic == n->isstatic)
637                         return n->func;
638         }
639
640         /* no function was found, throw exception */
641
642         *exceptionptr =
643                         new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
644                                                                          mname);
645
646         return NULL;
647 }
648 #endif /* defined(WITH_STATIC_CLASSPATH) */
649
650
651 /* native_make_overloaded_function *********************************************
652
653    XXX
654
655 *******************************************************************************/
656
657 #if !defined(WITH_STATIC_CLASSPATH)
658 static char *native_make_overloaded_function(char *name, utf *desc)
659 {
660         char *newname;
661         s4    namelen;
662         char *utf_ptr;
663         u2    c;
664         s4    i;
665
666         utf_ptr = desc->text;
667         namelen = strlen(name) + strlen("__") + strlen("0");
668
669         /* calculate additional length */
670
671         while ((c = utf_nextu2(&utf_ptr)) != ')') {
672                 switch (c) {
673                 case 'Z':
674                 case 'B':
675                 case 'C':
676                 case 'S':
677                 case 'I':
678                 case 'J':
679                 case 'F':
680                 case 'D':
681                         namelen++;
682                         break;
683                 case '[':
684                         namelen += 2;
685                         break;
686                 case 'L':
687                         namelen++;
688                         while (utf_nextu2(&utf_ptr) != ';')
689                                 namelen++;
690                         namelen += 2;
691                         break;
692                 case '(':
693                         break;
694                 default:
695                         assert(0);
696                 }
697         }
698
699
700         /* reallocate memory */
701
702         i = strlen(name);
703
704         newname = DMNEW(char, namelen);
705         MCOPY(newname, name, char, i);
706
707         utf_ptr = desc->text;
708
709         newname[i++] = '_';
710         newname[i++] = '_';
711
712         while ((c = utf_nextu2(&utf_ptr)) != ')') {
713                 switch (c) {
714                 case 'Z':
715                 case 'B':
716                 case 'C':
717                 case 'S':
718                 case 'J':
719                 case 'I':
720                 case 'F':
721                 case 'D':
722                         newname[i++] = c;
723                         break;
724                 case '[':
725                         newname[i++] = '_';
726                         newname[i++] = '3';
727                         break;
728                 case 'L':
729                         newname[i++] = 'L';
730                         while ((c = utf_nextu2(&utf_ptr)) != ';')
731                                 if (((c >= 'a') && (c <= 'z')) ||
732                                         ((c >= 'A') && (c <= 'Z')) ||
733                                         ((c >= '0') && (c <= '9')))
734                                         newname[i++] = c;
735                                 else
736                                         newname[i++] = '_';
737                         newname[i++] = '_';
738                         newname[i++] = '2';
739                         break;
740                 case '(':
741                         break;
742                 default:
743                         assert(0);
744                 }
745         }
746
747         /* close string */
748
749         newname[i] = '\0';
750
751         return newname;
752 }
753
754
755 /* native_insert_char **********************************************************
756
757    Inserts the passed UTF character into the native method name.  If
758    necessary it is escaped properly.
759
760 *******************************************************************************/
761
762 static s4 native_insert_char(char *name, u4 pos, u2 c)
763 {
764         s4 val;
765         s4 i;
766
767         switch (c) {
768         case '/':
769         case '.':
770                 /* replace '/' or '.' with '_' */
771                 name[pos] = '_';
772                 break;
773
774         case '_':
775                 /* escape sequence for '_' is '_1' */
776                 name[pos]   = '_';
777                 name[++pos] = '1';
778                 break;
779
780         case ';':
781                 /* escape sequence for ';' is '_2' */
782                 name[pos]   = '_';
783                 name[++pos] = '2';
784                 break;
785
786         case '[':
787                 /* escape sequence for '[' is '_1' */
788                 name[pos]   = '_';
789                 name[++pos] = '3';
790                 break;
791
792         default:
793                 if (isalnum(c))
794                         name[pos] = c;
795                 else {
796                         /* unicode character */
797                         name[pos]   = '_';
798                         name[++pos] = '0';
799
800                         for (i = 0; i < 4; ++i) {
801                                 val = c & 0x0f;
802                                 name[pos + 4 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
803                                 c >>= 4;
804                         }
805
806                         pos += 4;
807                 }
808                 break;
809         }
810
811         /* return the new buffer index */
812
813         return pos;
814 }
815
816
817 /* native_resolve_function *****************************************************
818
819    Resolves a native function, maybe from a dynamic library.
820
821 *******************************************************************************/
822
823 functionptr native_resolve_function(methodinfo *m)
824 {
825         lt_ptr                          sym;
826         char                           *name;
827         char                           *newname;
828         s4                              namelen;
829         char                           *utf_ptr;
830         char                           *utf_endptr;
831         u2                              c;
832         u4                              pos;
833         s4                              dumpsize;
834         hashtable_library_loader_entry *le;
835         hashtable_library_name_entry   *ne;
836         u4                              key;    /* hashkey                        */
837         u4                              slot;   /* slot in hashtable              */
838
839         /* verbose output */
840
841         if (opt_verbosejni) {
842                 printf("[Dynamic-linking native method ");
843                 utf_display_printable_ascii_classname(m->class->name);
844                 printf(".");
845                 utf_display_printable_ascii(m->name);
846                 printf(" ... ");
847         }
848                 
849         /* Calculate length of native function name.  We multiply the
850            class and method name length by 6 as this is the maxium
851            escape-sequence that can be generated (unicode). */
852
853         namelen = strlen("Java_") +
854                 utf_get_number_of_u2s(m->class->name) * 6 +
855                 strlen("_") +
856                 utf_get_number_of_u2s(m->name) * 6 +
857                 strlen("0");
858
859         /* allocate memory */
860
861         dumpsize = dump_size();
862
863         name = DMNEW(char, namelen);
864
865         /* generate name of native functions */
866
867         strcpy(name, "Java_");
868         pos = strlen("Java_");
869
870         utf_ptr    = m->class->name->text;
871         utf_endptr = UTF_END(m->class->name);
872
873         for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
874                 c   = *utf_ptr;
875                 pos = native_insert_char(name, pos, c);
876         }
877
878         /* seperator between class and method */
879
880         name[pos++] = '_';
881
882         utf_ptr    = m->name->text;
883         utf_endptr = UTF_END(m->name);
884
885         for (; utf_ptr < utf_endptr; utf_ptr++, pos++) {
886                 c   = *utf_ptr;
887                 pos = native_insert_char(name, pos, c);
888         }
889
890         /* close string */
891
892         name[pos] = '\0';
893
894         /* check for an buffer overflow */
895
896         assert(pos <= namelen);
897
898         /* generate overloaded function (having the types in it's name)           */
899
900         newname = native_make_overloaded_function(name, m->descriptor);
901
902         /* check the library hash entries of the classloader of the
903            methods's class  */
904
905         sym = NULL;
906
907         /* normally addresses are aligned to 4, 8 or 16 bytes */
908
909         key  = ((u4) (ptrint) m->class->classloader) >> 4;    /* align to 16-byte */
910         slot = key & (hashtable_library->size - 1);
911         le   = hashtable_library->ptr[slot];
912
913         /* iterate through loaders in this hash slot */
914
915         while ((le != NULL) && (sym == NULL)) {
916                 /* iterate through names in this loader */
917
918                 ne = le->namelink;
919                         
920                 while ((ne != NULL) && (sym == NULL)) {
921                         sym = lt_dlsym(ne->handle, name);
922
923                         if (sym == NULL)
924                                 sym = lt_dlsym(ne->handle, newname);
925
926                         ne = ne->hashlink;
927                 }
928
929                 le = le->hashlink;
930         }
931
932         if (sym != NULL)
933                 if (opt_verbosejni)
934                         printf("JNI ]\n");
935
936
937         /* If not found, try to find the native function symbol in the
938            main program. */
939
940         if (sym == NULL) {
941                 sym = lt_dlsym(mainhandle, name);
942
943                 if (sym == NULL)
944                         sym = lt_dlsym(mainhandle, newname);
945
946                 if (sym != NULL)
947                         if (opt_verbosejni)
948                                 printf("internal ]\n");
949         }
950
951
952 #if defined(ENABLE_JVMTI)
953         /* fire Native Method Bind event */
954         if (jvmti) jvmti_NativeMethodBind(m, sym, &sym);
955 #endif
956
957         /* no symbol found? throw exception */
958
959         if (sym == NULL) {
960                 if (opt_verbosejni)
961                         printf("failed ]\n");
962
963                 exceptions_throw_unsatisfiedlinkerror(m->name);
964         }
965
966         /* release memory */
967
968         dump_release(dumpsize);
969
970         return (functionptr) (ptrint) sym;
971 }
972 #endif /* !defined(WITH_STATIC_CLASSPATH) */
973
974
975 /* native_new_and_init *********************************************************
976
977    Creates a new object on the heap and calls the initializer.
978    Returns the object pointer or NULL if memory is exhausted.
979                         
980 *******************************************************************************/
981
982 java_objectheader *native_new_and_init(classinfo *c)
983 {
984         methodinfo *m;
985         java_objectheader *o;
986
987         if (c == NULL)
988                 vm_abort("native_new_and_init: c == NULL");
989
990         /* create object */
991
992         o = builtin_new(c);
993         
994         if (o == NULL)
995                 return NULL;
996
997         /* try to find the initializer */
998
999         m = class_findmethod(c, utf_init, utf_void__void);
1000                                                       
1001         /* ATTENTION: returning the object here is ok, since the class may
1002        not have an initializer */
1003
1004         if (m == NULL)
1005                 return o;
1006
1007         /* call initializer */
1008
1009         (void) vm_call_method(m, o);
1010
1011         return o;
1012 }
1013
1014
1015 java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s)
1016 {
1017         methodinfo        *m;
1018         java_objectheader *o;
1019
1020         if (c == NULL)
1021                 vm_abort("native_new_and_init_string: c == NULL");
1022
1023         /* create object */
1024
1025         o = builtin_new(c);
1026
1027         if (o == NULL)
1028                 return NULL;
1029
1030         /* find initializer */
1031
1032         m = class_resolveclassmethod(c,
1033                                                                  utf_init,
1034                                                                  utf_java_lang_String__void,
1035                                                                  NULL,
1036                                                                  true);
1037
1038         /* initializer not found */
1039
1040         if (m == NULL)
1041                 return NULL;
1042
1043         /* call initializer */
1044
1045         (void) vm_call_method(m, o, s);
1046
1047         return o;
1048 }
1049
1050
1051 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
1052 {
1053         methodinfo *m;
1054         java_objectheader *o;
1055
1056         if (c == NULL)
1057                 vm_abort("native_new_and_init_int: c == NULL");
1058
1059         /* create object */
1060
1061         o = builtin_new(c);
1062         
1063         if (o == NULL)
1064                 return NULL;
1065
1066         /* find initializer */
1067
1068         m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
1069
1070         /* initializer not found  */
1071
1072         if (m == NULL)
1073                 return NULL;
1074
1075         /* call initializer */
1076
1077         (void) vm_call_method(m, o, i);
1078
1079         return o;
1080 }
1081
1082
1083 java_objectheader *native_new_and_init_throwable(classinfo *c, java_objectheader *t)
1084 {
1085         java_objectheader *o;
1086         methodinfo        *m;
1087
1088         if (c == NULL)
1089                 vm_abort("native_new_and_init_throwable: c == NULL");
1090
1091         /* create object */
1092
1093         o = builtin_new(c);
1094         
1095         if (o == NULL)
1096                 return NULL;
1097
1098         /* find initializer */
1099
1100         m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
1101                                                       
1102         /* initializer not found */
1103
1104         if (m == NULL)
1105                 return NULL;
1106
1107         /* call initializer */
1108
1109         (void) vm_call_method(m, o, t);
1110
1111         return o;
1112 }
1113
1114
1115 /* native_class_getdeclaredannotations *****************************************
1116
1117    Implementation for
1118    java.lang.Class.getDeclaredAnnotations(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
1119
1120 *******************************************************************************/
1121
1122 #if defined(ENABLE_JAVASE)
1123 java_objectarray *native_class_getdeclaredannotations(classinfo *c)
1124 {
1125         java_objectarray *oa;
1126         s4                count;
1127         s4                i;
1128
1129         classinfo *class_java_lang_annotation_Annotation;
1130
1131         /* create Annotation-array */
1132
1133         /* XXX should we cache that class? */
1134         if (!(class_java_lang_annotation_Annotation =
1135                   load_class_bootstrap(utf_new_char("java/lang/annotation/Annotation"))))
1136                 return NULL;
1137
1138         count = c->runtimevisibleannotationscount;
1139
1140         oa = builtin_anewarray(count, class_java_lang_annotation_Annotation);
1141
1142         if (oa == NULL)
1143                 return NULL;
1144
1145         /* fill the annotations */
1146
1147         for (i = 0; i < count; i++) {
1148         }
1149
1150         return oa;
1151 }
1152 #endif
1153
1154
1155 /*
1156  * These are local overrides for various environment variables in Emacs.
1157  * Please do not remove this and leave it at the end of the file, where
1158  * Emacs will automagically detect them.
1159  * ---------------------------------------------------------------------
1160  * Local variables:
1161  * mode: c
1162  * indent-tabs-mode: t
1163  * c-basic-offset: 4
1164  * tab-width: 4
1165  * End:
1166  */