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