* Updated header: Added 2006. Changed address of FSF. Changed email
[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 4357 2006-01-22 23:33:38Z twisti $
34
35 */
36
37
38 #include "config.h"
39
40 #include <assert.h>
41
42 #if !defined(ENABLE_STATICVM)
43 # include <ltdl.h>
44 #endif
45
46 #include "vm/types.h"
47
48 #include "cacao/cacao.h"
49 #include "mm/memory.h"
50 #include "native/jni.h"
51 #include "native/native.h"
52 #include "native/include/java_lang_Throwable.h"
53 #include "toolbox/logging.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/hashtable.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/resolve.h"
61 #include "vm/stringlocal.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
91 #if defined(ENABLE_STATICVM)
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(ENABLE_STATICVM) */
114
115 /* Ensure that symbols for functions implemented within CACAO are used and    */
116 /* 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(ENABLE_STATICVM) */
227
228
229 /* tables for methods *********************************************************/
230
231 #ifdef ENABLE_STATICVM
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(ENABLE_STATICVM)
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(ENABLE_STATICVM)
259         void *p;
260
261         /* We need to access the dummy native table, not only to remove a warning */
262         /* but to be sure that the table is not optimized away (gcc does this     */
263         /* 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
285 #endif
286
287         /* everything's ok */
288
289         return true;
290 }
291
292
293 /* native_hashtable_library_add ************************************************
294
295    Adds an entry to the native library hashtable.
296
297 *******************************************************************************/
298
299 #if !defined(ENABLE_STATICVM)
300 void native_hashtable_library_add(utf *filename, java_objectheader *loader,
301                                                                   lt_dlhandle handle)
302 {
303         hashtable_library_loader_entry *le;
304         hashtable_library_name_entry   *ne; /* library name                       */
305         u4   key;                           /* hashkey                            */
306         u4   slot;                          /* slot in hashtable                  */
307
308         /* normally addresses are aligned to 4, 8 or 16 bytes */
309
310         key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
311         slot = key & (hashtable_library.size - 1);
312         le   = hashtable_library.ptr[slot];
313
314         /* search external hash chain for the entry */
315
316         while (le) {
317                 if (le->loader == loader)
318                         break;
319
320                 le = le->hashlink;                  /* next element in external chain */
321         }
322
323         /* no loader found? create a new entry */
324
325         if (!le) {
326                 le = NEW(hashtable_library_loader_entry);
327
328                 le->loader = loader;
329                 le->namelink = NULL;
330
331                 /* insert entry into hashtable */
332
333                 le->hashlink =
334                         (hashtable_library_loader_entry *) hashtable_library.ptr[slot];
335                 hashtable_library.ptr[slot] = le;
336
337                 /* update number of hashtable-entries */
338
339                 hashtable_library.entries++;
340         }
341
342
343         /* search for library name */
344
345         ne = le->namelink;
346
347         while (ne) {
348                 if (ne->name == filename)
349                         return;
350
351                 ne = ne->hashlink;                  /* next element in external chain */
352         }
353
354         /* not found? add the library name to the classloader */
355
356         ne = NEW(hashtable_library_name_entry);
357
358         ne->name = filename;
359         ne->handle = handle;
360
361         /* insert entry into external chain */
362
363         ne->hashlink = le->namelink;
364         le->namelink = ne;
365 }
366 #endif /* !defined(ENABLE_STATICVM) */
367
368
369 /* native_hashtable_library_find ***********************************************
370
371    Find an entry in the native library hashtable.
372
373 *******************************************************************************/
374
375 #if !defined(ENABLE_STATICVM)
376 hashtable_library_name_entry *native_hashtable_library_find(utf *filename,
377                                                                                                                         java_objectheader *loader)
378 {
379         hashtable_library_loader_entry *le;
380         hashtable_library_name_entry   *ne; /* library name                       */
381         u4   key;                           /* hashkey                            */
382         u4   slot;                          /* slot in hashtable                  */
383
384         /* normally addresses are aligned to 4, 8 or 16 bytes */
385
386         key  = ((u4) (ptrint) loader) >> 4;        /* align to 16-byte boundaries */
387         slot = key & (hashtable_library.size - 1);
388         le   = hashtable_library.ptr[slot];
389
390         /* search external hash chain for the entry */
391
392         while (le) {
393                 if (le->loader == loader)
394                         break;
395
396                 le = le->hashlink;                  /* next element in external chain */
397         }
398
399         /* no loader found? return NULL */
400
401         if (!le)
402                 return NULL;
403
404         /* search for library name */
405
406         ne = le->namelink;
407
408         while (ne) {
409                 if (ne->name == filename)
410                         return ne;
411
412                 ne = ne->hashlink;                  /* next element in external chain */
413         }
414
415         /* return entry, if no entry was found, ne is NULL */
416
417         return ne;
418 }
419 #endif /* !defined(ENABLE_STATICVM) */
420
421
422 /* native_findfunction *********************************************************
423
424    Looks up a method (must have the same class name, method name,
425    descriptor and 'static'ness) and returns a function pointer to it.
426    Returns: function pointer or NULL (if there is no such method)
427
428    Remark: For faster operation, the names/descriptors are converted
429    from C strings to Unicode the first time this function is called.
430
431 *******************************************************************************/
432
433 #if defined(ENABLE_STATICVM)
434 functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
435                                                                 bool isstatic)
436 {
437         /* entry of table for fast string comparison */
438         struct nativecompref *n;
439         s4 i;
440
441         isstatic = isstatic ? true : false;
442         
443         if (!nativecompdone) {
444                 for (i = 0; i < NATIVETABLESIZE; i++) {
445                         nativecomptable[i].classname  = 
446                                 utf_new_char(nativetable[i].classname);
447
448                         nativecomptable[i].methodname = 
449                                 utf_new_char(nativetable[i].methodname);
450
451                         nativecomptable[i].descriptor =
452                                 utf_new_char(nativetable[i].descriptor);
453
454                         nativecomptable[i].isstatic   = nativetable[i].isstatic;
455                         nativecomptable[i].func       = nativetable[i].func;
456                 }
457
458                 nativecompdone = true;
459         }
460
461         for (i = 0; i < NATIVETABLESIZE; i++) {
462                 n = &(nativecomptable[i]);
463
464                 if (cname == n->classname && mname == n->methodname &&
465                     desc == n->descriptor && isstatic == n->isstatic)
466                         return n->func;
467         }
468
469                 
470         /* no function was found, throw exception */
471
472         *exceptionptr =
473                         new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
474                                                                          mname);
475
476         return NULL;
477 }
478 #endif /* defined(ENABLE_STATICVM) */
479
480
481 /* native_make_overloaded_function *********************************************
482
483    XXX
484
485 *******************************************************************************/
486
487 #if !defined(ENABLE_STATICVM)
488 static char *native_make_overloaded_function(char *name, utf *desc)
489 {
490         char *newname;
491         s4    namelen;
492         char *utf_ptr;
493         u2    c;
494         s4    i;
495
496         utf_ptr = desc->text;
497         namelen = strlen(name) + strlen("__") + strlen("0");
498
499         /* calculate additional length */
500
501         while ((c = utf_nextu2(&utf_ptr)) != ')') {
502                 switch (c) {
503                 case 'Z':
504                 case 'B':
505                 case 'C':
506                 case 'S':
507                 case 'I':
508                 case 'J':
509                 case 'F':
510                 case 'D':
511                         namelen++;
512                         break;
513                 case '[':
514                         namelen += 2;
515                         break;
516                 case 'L':
517                         namelen++;
518                         while (utf_nextu2(&utf_ptr) != ';')
519                                 namelen++;
520                         namelen += 2;
521                         break;
522                 case '(':
523                         break;
524                 default:
525                         assert(0);
526                 }
527         }
528
529
530         /* reallocate memory */
531
532         i = strlen(name);
533
534         newname = DMNEW(char, namelen);
535         MCOPY(newname, name, char, i);
536
537         utf_ptr = desc->text;
538
539         newname[i++] = '_';
540         newname[i++] = '_';
541
542         while ((c = utf_nextu2(&utf_ptr)) != ')') {
543                 switch (c) {
544                 case 'Z':
545                 case 'B':
546                 case 'C':
547                 case 'S':
548                 case 'J':
549                 case 'I':
550                 case 'F':
551                 case 'D':
552                         newname[i++] = c;
553                         break;
554                 case '[':
555                         newname[i++] = '_';
556                         newname[i++] = '3';
557                         break;
558                 case 'L':
559                         newname[i++] = 'L';
560                         while ((c = utf_nextu2(&utf_ptr)) != ';')
561                                 if (((c >= 'a') && (c <= 'z')) ||
562                                         ((c >= 'A') && (c <= 'Z')) ||
563                                         ((c >= '0') && (c <= '9')))
564                                         newname[i++] = c;
565                                 else
566                                         newname[i++] = '_';
567                         newname[i++] = '_';
568                         newname[i++] = '2';
569                         break;
570                 case '(':
571                         break;
572                 default:
573                         assert(0);
574                 }
575         }
576
577         /* close string */
578
579         newname[i] = '\0';
580
581         return newname;
582 }
583
584
585 /* native_resolve_function *****************************************************
586
587    Resolves a native function, maybe from a dynamic library.
588
589 *******************************************************************************/
590
591 functionptr native_resolve_function(methodinfo *m)
592 {
593         lt_ptr                     sym;
594         char                      *name;
595         char                      *newname;
596         s4                         namelen;
597         char                      *utf_ptr;
598         char                      *utf_endptr;
599         s4                         dumpsize;
600         hashtable_library_loader_entry *le;
601         hashtable_library_name_entry   *ne;
602         u4                         key;     /* hashkey                            */
603         u4                         slot;    /* slot in hashtable                  */
604         u4                         i;
605
606
607         /* verbose output */
608
609         if (opt_verbosejni) {
610                 printf("[Dynamic-linking native method ");
611                 utf_display_classname(m->class->name);
612                 printf(".");
613                 utf_display(m->name);
614                 printf(" ... ");
615         }
616                 
617         /* calculate length of native function name */
618
619         namelen = strlen("Java_") + utf_strlen(m->class->name) + strlen("_") +
620                 utf_strlen(m->name) + strlen("0");
621
622         /* check for underscores in class name */
623
624         utf_ptr = m->class->name->text;
625         utf_endptr = UTF_END(m->class->name);
626
627         while (utf_ptr < utf_endptr)
628                 if (utf_nextu2(&utf_ptr) == '_')
629                         namelen++;
630
631         /* check for underscores in method name */
632
633         utf_ptr = m->name->text;
634         utf_endptr = UTF_END(m->name);
635
636         while (utf_ptr < utf_endptr)
637                 if (utf_nextu2(&utf_ptr) == '_')
638                         namelen++;
639
640         /* allocate memory */
641
642         dumpsize = dump_size();
643
644         name = DMNEW(char, namelen);
645
646
647         /* generate name of native functions */
648
649         strcpy(name, "Java_");
650         i = strlen("Java_");
651
652         utf_ptr = m->class->name->text;
653         utf_endptr = UTF_END(m->class->name);
654
655         for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
656                 name[i] = *utf_ptr;
657
658                 /* escape sequence for '_' is '_1' */
659
660                 if (name[i] == '_')
661                         name[++i] = '1';
662
663                 /* replace '/' with '_' */
664
665                 if (name[i] == '/')
666                         name[i] = '_';
667         }
668
669         /* seperator between class and method */
670
671         name[i++] = '_';
672
673         utf_ptr = m->name->text;
674         utf_endptr = UTF_END(m->name);
675
676         for (; utf_ptr < utf_endptr; utf_ptr++, i++) {
677                 name[i] = *utf_ptr;
678
679                 /* escape sequence for '_' is '_1' */
680
681                 if (name[i] == '_')
682                         name[++i] = '1';
683         }
684
685         /* close string */
686
687         name[i] = '\0';
688
689
690         /* generate overloaded function (having the types in it's name)           */
691
692         newname = native_make_overloaded_function(name, m->descriptor);
693
694         /* check the library hash entries of the classloader of the methods's     */
695         /* class                                                                  */
696
697         sym = NULL;
698
699         /* normally addresses are aligned to 4, 8 or 16 bytes */
700
701         key  = ((u4) (ptrint) m->class->classloader) >> 4;    /* align to 16-byte */
702         slot = key & (hashtable_library.size - 1);
703         le   = hashtable_library.ptr[slot];
704
705         /* iterate through loaders in this hash slot */
706
707         while (le && !sym) {
708                 /* iterate through names in this loader */
709
710                 ne = le->namelink;
711                         
712                 while (ne && !sym) {
713                         sym = lt_dlsym(ne->handle, name);
714
715                         if (!sym)
716                                 sym = lt_dlsym(ne->handle, newname);
717
718                         ne = ne->hashlink;
719                 }
720
721                 le = le->hashlink;
722         }
723
724         if (sym)
725                 if (opt_verbosejni)
726                         printf("JNI ]\n");
727
728
729         /* if not found, try to find the native function symbol in the main       */
730         /* program                                                                */
731
732         if (!sym) {
733                 sym = lt_dlsym(mainhandle, name);
734
735                 if (!sym)
736                         sym = lt_dlsym(mainhandle, newname);
737
738                 if (sym)
739                         if (opt_verbosejni)
740                                 printf("internal ]\n");
741         }
742
743
744         /* no symbol found? throw exception */
745
746         if (!sym)
747                 *exceptionptr =
748                         new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
749                                                                          m->name);
750
751         /* release memory */
752
753         dump_release(dumpsize);
754
755         return (functionptr) (ptrint) sym;
756 }
757 #endif /* !defined(ENABLE_STATICVM) */
758
759
760 /* native_new_and_init *********************************************************
761
762    Creates a new object on the heap and calls the initializer.
763    Returns the object pointer or NULL if memory is exhausted.
764                         
765 *******************************************************************************/
766
767 java_objectheader *native_new_and_init(classinfo *c)
768 {
769         methodinfo *m;
770         java_objectheader *o;
771
772         if (!c)
773                 return *exceptionptr;
774
775         /* create object */
776
777         o = builtin_new(c);
778         
779         if (!o)
780                 return NULL;
781
782         /* try to find the initializer */
783
784         m = class_findmethod(c, utf_init, utf_void__void);
785                                                       
786         /* ATTENTION: returning the object here is ok, since the class may
787        not have an initializer */
788
789         if (!m)
790                 return o;
791
792         /* call initializer */
793
794         ASM_CALLJAVAFUNCTION(m, o, NULL, NULL, NULL);
795
796         return o;
797 }
798
799
800 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
801 {
802         methodinfo *m;
803         java_objectheader *o;
804
805         if (!c)
806                 return *exceptionptr;
807
808         /* create object */
809
810         o = builtin_new(c);
811
812         if (!o)
813                 return NULL;
814
815         /* find initializer */
816
817         m = class_resolveclassmethod(c,
818                                                                  utf_init,
819                                                                  utf_java_lang_String__void,
820                                                                  NULL,
821                                                                  true);
822
823         /* initializer not found */
824
825         if (!m)
826                 return NULL;
827
828         /* call initializer */
829
830         ASM_CALLJAVAFUNCTION(m, o, s, NULL, NULL);
831
832         return o;
833 }
834
835
836 java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
837 {
838         methodinfo *m;
839         java_objectheader *o;
840
841         if (!c)
842                 return *exceptionptr;
843
844         /* create object */
845
846         o = builtin_new(c);
847         
848         if (!o)
849                 return NULL;
850
851         /* find initializer */
852
853         m = class_resolveclassmethod(c, utf_init, utf_int__void, NULL, true);
854
855         /* initializer not found  */
856
857         if (!m)
858                 return NULL;
859
860         /* call initializer */
861
862         ASM_CALLJAVAFUNCTION(m, o, (void *) (ptrint) i, NULL, NULL);
863
864         return o;
865 }
866
867
868 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
869 {
870         methodinfo *m;
871         java_objectheader *o;
872
873         if (!c)
874                 return *exceptionptr;
875
876         /* create object */
877
878         o = builtin_new(c);
879         
880         if (!o)
881                 return NULL;
882
883         /* find initializer */
884
885         m = class_findmethod(c, utf_init, utf_java_lang_Throwable__void);
886                                                       
887         /* initializer not found */
888
889         if (!m)
890                 return NULL;
891
892         /* call initializer */
893
894         ASM_CALLJAVAFUNCTION(m, o, t, NULL, NULL);
895
896         return o;
897 }
898
899
900 /* native_get_parametertypes ***************************************************
901
902    Use the descriptor of a method to generate a java/lang/Class array
903    which contains the classes of the parametertypes of the method.
904
905 *******************************************************************************/
906
907 java_objectarray *native_get_parametertypes(methodinfo *m)
908 {
909         methoddesc       *md;
910         typedesc         *paramtypes;
911         s4                paramcount;
912     java_objectarray *oa;
913         s4                i;
914
915         md = m->parseddesc;
916
917         /* is the descriptor fully parsed? */
918
919         if (!m->parseddesc->params)
920                 if (!descriptor_params_from_paramtypes(md, m->flags))
921                         return NULL;
922
923         paramtypes = md->paramtypes;
924         paramcount = md->paramcount;
925
926         /* skip `this' pointer */
927
928         if (!(m->flags & ACC_STATIC)) {
929                 paramtypes++;
930                 paramcount--;
931         }
932
933         /* create class-array */
934
935         oa = builtin_anewarray(paramcount, class_java_lang_Class);
936
937         if (!oa)
938                 return NULL;
939
940     /* get classes */
941
942         for (i = 0; i < paramcount; i++)
943                 if (!resolve_class_from_typedesc(&paramtypes[i], true, false,
944                                                                                  (classinfo **) &oa->data[i]))
945                         return NULL;
946
947         return oa;
948 }
949
950
951 /* native_get_exceptiontypes ***************************************************
952
953    Get the exceptions which can be thrown by a method.
954
955 *******************************************************************************/
956
957 java_objectarray *native_get_exceptiontypes(methodinfo *m)
958 {
959         java_objectarray *oa;
960         classinfo        *c;
961         u2                i;
962
963         /* create class-array */
964
965         oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
966
967         if (!oa)
968                 return NULL;
969
970         for (i = 0; i < m->thrownexceptionscount; i++) {
971                 if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[i],
972                                                                                    resolveEager, true, false, &c))
973                         return NULL;
974
975                 oa->data[i] = (java_objectheader *) c;
976         }
977
978         return oa;
979 }
980
981
982 /* native_get_returntype *******************************************************
983
984    Get the returntype class of a method.
985
986 *******************************************************************************/
987
988 classinfo *native_get_returntype(methodinfo *m)
989 {
990         classinfo *c;
991
992         if (!resolve_class_from_typedesc(&(m->parseddesc->returntype), true, false,
993                                                                          &c))
994                 return NULL;
995
996         return c;
997 }
998
999
1000 /*
1001  * These are local overrides for various environment variables in Emacs.
1002  * Please do not remove this and leave it at the end of the file, where
1003  * Emacs will automagically detect them.
1004  * ---------------------------------------------------------------------
1005  * Local variables:
1006  * mode: c
1007  * indent-tabs-mode: t
1008  * c-basic-offset: 4
1009  * tab-width: 4
1010  * End:
1011  */