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