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