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