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