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