d7dac000d7489f84db550cf10c29e72ffe3b5c39
[cacao.git] / src / native / jni.c
1 /* src/native/jni.c - implementation of the Java Native Interface functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: jni.c 8335 2007-08-17 11:04:35Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdint.h>
34 #include <string.h>
35
36 #include "vm/types.h"
37
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
40
41 #include "native/jni.h"
42 #include "native/llni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
45
46 #if defined(ENABLE_JAVASE)
47 # if defined(WITH_CLASSPATH_GNU)
48 #  include "native/include/gnu_classpath_Pointer.h"
49
50 #  if SIZEOF_VOID_P == 8
51 #   include "native/include/gnu_classpath_Pointer64.h"
52 #  else
53 #   include "native/include/gnu_classpath_Pointer32.h"
54 #  endif
55 # endif
56 #endif
57
58 #include "native/include/java_lang_Object.h"
59 #include "native/include/java_lang_Byte.h"
60 #include "native/include/java_lang_Character.h"
61 #include "native/include/java_lang_Short.h"
62 #include "native/include/java_lang_Integer.h"
63 #include "native/include/java_lang_Boolean.h"
64 #include "native/include/java_lang_Long.h"
65 #include "native/include/java_lang_Float.h"
66 #include "native/include/java_lang_Double.h"
67 #include "native/include/java_lang_String.h"
68 #include "native/include/java_lang_Throwable.h"
69
70 #if defined(ENABLE_JAVASE)
71 # if defined(WITH_CLASSPATH_SUN)
72 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
73 # endif
74
75 # include "native/include/java_lang_ClassLoader.h"
76
77 # include "native/include/java_lang_reflect_Constructor.h"
78 # include "native/include/java_lang_reflect_Field.h"
79 # include "native/include/java_lang_reflect_Method.h"
80
81 # include "native/include/java_nio_Buffer.h"
82
83 # if defined(WITH_CLASSPATH_GNU)
84 #  include "native/include/java_nio_DirectByteBufferImpl.h"
85 # endif
86 #endif
87
88 #if defined(ENABLE_JVMTI)
89 # include "native/jvmti/cacaodbg.h"
90 #endif
91
92 #include "native/vm/java_lang_Class.h"
93
94 #if defined(ENABLE_JAVASE)
95 # include "native/vm/java_lang_ClassLoader.h"
96 # include "native/vm/reflect.h"
97 #endif
98
99 #include "threads/lock-common.h"
100 #include "threads/threads-common.h"
101
102 #include "toolbox/logging.h"
103
104 #include "vm/builtin.h"
105 #include "vm/exceptions.h"
106 #include "vm/global.h"
107 #include "vm/initialize.h"
108 #include "vm/primitive.h"
109 #include "vm/resolve.h"
110 #include "vm/stringlocal.h"
111 #include "vm/vm.h"
112
113 #include "vm/jit/asmpart.h"
114 #include "vm/jit/jit.h"
115 #include "vm/jit/stacktrace.h"
116
117 #include "vmcore/loader.h"
118 #include "vmcore/options.h"
119 #include "vmcore/statistics.h"
120
121
122 /* debug **********************************************************************/
123
124 #if !defined(NDEBUG)
125 # define TRACEJNICALLS(format, ...) \
126     do { \
127         if (opt_TraceJNICalls) { \
128             log_println((format), __VA_ARGS__); \
129         } \
130     } while (0)
131 #else
132 # define TRACEJNICALLS(format, ...)
133 #endif
134
135
136 /* global variables ***********************************************************/
137
138 /* global reference table *****************************************************/
139
140 /* hashsize must be power of 2 */
141
142 #define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
143
144 static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
145
146
147 /* direct buffer stuff ********************************************************/
148
149 #if defined(ENABLE_JAVASE)
150 static classinfo *class_java_nio_Buffer;
151 static classinfo *class_java_nio_DirectByteBufferImpl;
152 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
153
154 # if defined(WITH_CLASSPATH_GNU)
155 #  if SIZEOF_VOID_P == 8
156 static classinfo *class_gnu_classpath_Pointer64;
157 #  else
158 static classinfo *class_gnu_classpath_Pointer32;
159 #  endif
160 # endif
161
162 static methodinfo *dbbirw_init;
163 #endif
164
165
166 /* accessing instance fields macros *******************************************/
167
168 #define SET_FIELD(o,type,f,value) \
169     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
170
171 #define GET_FIELD(o,type,f) \
172     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
173
174
175 /* some forward declarations **************************************************/
176
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
178 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
179
180
181 /* jni_init ********************************************************************
182
183    Initialize the JNI subsystem.
184
185 *******************************************************************************/
186
187 bool jni_init(void)
188 {
189         /* create global ref hashtable */
190
191         hashtable_global_ref = NEW(hashtable);
192
193         hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
194
195
196 #if defined(ENABLE_JAVASE)
197         /* direct buffer stuff */
198
199         if (!(class_java_nio_Buffer =
200                   load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
201                 !link_class(class_java_nio_Buffer))
202                 return false;
203
204 # if defined(WITH_CLASSPATH_GNU)
205         if (!(class_java_nio_DirectByteBufferImpl =
206                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207                 !link_class(class_java_nio_DirectByteBufferImpl))
208                 return false;
209
210         if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212                 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
213                 return false;
214
215         if (!(dbbirw_init =
216                 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
217                                                         utf_init,
218                                                         utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
219                 return false;
220
221 #  if SIZEOF_VOID_P == 8
222         if (!(class_gnu_classpath_Pointer64 =
223                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224                 !link_class(class_gnu_classpath_Pointer64))
225                 return false;
226 #  else
227         if (!(class_gnu_classpath_Pointer32 =
228                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229                 !link_class(class_gnu_classpath_Pointer32))
230                 return false;
231 #  endif
232 # endif
233 #endif /* defined(ENABLE_JAVASE) */
234
235         return true;
236 }
237
238
239 /* jni_init_localref_table *****************************************************
240
241    Frees the local references table of the current thread.
242
243 *******************************************************************************/
244
245 bool jni_free_localref_table(void)
246 {
247         localref_table *lrt;
248
249 #if defined(ENABLE_GC_CACAO)
250         lrt = LOCALREFTABLE;
251
252         assert(lrt);
253         assert(lrt->prev == NULL);
254
255         FREE(lrt, localref_table);
256
257         LOCALREFTABLE = NULL;
258 #endif
259
260         return true;
261 }
262
263
264 /* _Jv_jni_CallObjectMethod ****************************************************
265
266    Internal function to call Java Object methods.
267
268 *******************************************************************************/
269
270 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
271                                                                                            vftbl_t *vftbl,
272                                                                                            methodinfo *m, va_list ap)
273 {
274         methodinfo    *resm;
275         java_handle_t *ro;
276
277         STATISTICS(jniinvokation());
278
279         if (m == NULL) {
280                 exceptions_throw_nullpointerexception();
281                 return NULL;
282         }
283
284         /* Class initialization is done by the JIT compiler.  This is ok
285            since a static method always belongs to the declaring class. */
286
287         if (m->flags & ACC_STATIC) {
288                 /* For static methods we reset the object. */
289
290                 if (o != NULL)
291                         o = NULL;
292
293                 /* for convenience */
294
295                 resm = m;
296
297         } else {
298                 /* For instance methods we make a virtual function table lookup. */
299
300                 resm = method_vftbl_lookup(vftbl, m);
301         }
302
303         STATISTICS(jnicallXmethodnvokation());
304
305         ro = vm_call_method_valist(resm, o, ap);
306
307         return ro;
308 }
309
310
311 /* _Jv_jni_CallObjectMethodA ***************************************************
312
313    Internal function to call Java Object methods.
314
315 *******************************************************************************/
316
317 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
318                                                                                                 vftbl_t *vftbl,
319                                                                                                 methodinfo *m,
320                                                                                                 const jvalue *args)
321 {
322         methodinfo    *resm;
323         java_handle_t *ro;
324
325         STATISTICS(jniinvokation());
326
327         if (m == NULL) {
328                 exceptions_throw_nullpointerexception();
329                 return NULL;
330         }
331
332         /* Class initialization is done by the JIT compiler.  This is ok
333            since a static method always belongs to the declaring class. */
334
335         if (m->flags & ACC_STATIC) {
336                 /* For static methods we reset the object. */
337
338                 if (o != NULL)
339                         o = NULL;
340
341                 /* for convenience */
342
343                 resm = m;
344
345         } else {
346                 /* For instance methods we make a virtual function table lookup. */
347
348                 resm = method_vftbl_lookup(vftbl, m);
349         }
350
351         STATISTICS(jnicallXmethodnvokation());
352
353         ro = vm_call_method_jvalue(resm, o, args);
354
355         return ro;
356 }
357
358
359 /* _Jv_jni_CallIntMethod *******************************************************
360
361    Internal function to call Java integer class methods (boolean,
362    byte, char, short, int).
363
364 *******************************************************************************/
365
366 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
367                                                                   methodinfo *m, va_list ap)
368 {
369         methodinfo *resm;
370         jint        i;
371
372         STATISTICS(jniinvokation());
373
374         if (m == NULL) {
375                 exceptions_throw_nullpointerexception();
376                 return 0;
377         }
378         
379         /* Class initialization is done by the JIT compiler.  This is ok
380            since a static method always belongs to the declaring class. */
381
382         if (m->flags & ACC_STATIC) {
383                 /* For static methods we reset the object. */
384
385                 if (o != NULL)
386                         o = NULL;
387
388                 /* for convenience */
389
390                 resm = m;
391
392         } else {
393                 /* For instance methods we make a virtual function table lookup. */
394
395                 resm = method_vftbl_lookup(vftbl, m);
396         }
397
398         STATISTICS(jnicallXmethodnvokation());
399
400         i = vm_call_method_int_valist(resm, o, ap);
401
402         return i;
403 }
404
405
406 /* _Jv_jni_CallIntMethodA ******************************************************
407
408    Internal function to call Java integer class methods (boolean,
409    byte, char, short, int).
410
411 *******************************************************************************/
412
413 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
414                                                                    methodinfo *m, const jvalue *args)
415 {
416         methodinfo *resm;
417         jint        i;
418
419         STATISTICS(jniinvokation());
420
421         if (m == NULL) {
422                 exceptions_throw_nullpointerexception();
423                 return 0;
424         }
425         
426         /* Class initialization is done by the JIT compiler.  This is ok
427            since a static method always belongs to the declaring class. */
428
429         if (m->flags & ACC_STATIC) {
430                 /* For static methods we reset the object. */
431
432                 if (o != NULL)
433                         o = NULL;
434
435                 /* for convenience */
436
437                 resm = m;
438
439         } else {
440                 /* For instance methods we make a virtual function table lookup. */
441
442                 resm = method_vftbl_lookup(vftbl, m);
443         }
444
445         STATISTICS(jnicallXmethodnvokation());
446
447         i = vm_call_method_int_jvalue(resm, o, args);
448
449         return i;
450 }
451
452
453 /* _Jv_jni_CallLongMethod ******************************************************
454
455    Internal function to call Java long methods.
456
457 *******************************************************************************/
458
459 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
460                                                                         methodinfo *m, va_list ap)
461 {
462         methodinfo *resm;
463         jlong       l;
464
465         STATISTICS(jniinvokation());
466
467         if (m == NULL) {
468                 exceptions_throw_nullpointerexception();
469                 return 0;
470         }
471
472         /* Class initialization is done by the JIT compiler.  This is ok
473            since a static method always belongs to the declaring class. */
474
475         if (m->flags & ACC_STATIC) {
476                 /* For static methods we reset the object. */
477
478                 if (o != NULL)
479                         o = NULL;
480
481                 /* for convenience */
482
483                 resm = m;
484
485         } else {
486                 /* For instance methods we make a virtual function table lookup. */
487
488                 resm = method_vftbl_lookup(vftbl, m);
489         }
490
491         STATISTICS(jnicallXmethodnvokation());
492
493         l = vm_call_method_long_valist(resm, o, ap);
494
495         return l;
496 }
497
498
499 /* _Jv_jni_CallLongMethodA *****************************************************
500
501    Internal function to call Java long methods.
502
503 *******************************************************************************/
504
505 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
506                                                                          methodinfo *m, const jvalue *args)
507 {
508         methodinfo *resm;
509         jlong       l;
510
511         STATISTICS(jniinvokation());
512
513         if (m == NULL) {
514                 exceptions_throw_nullpointerexception();
515                 return 0;
516         }
517
518         /* Class initialization is done by the JIT compiler.  This is ok
519            since a static method always belongs to the declaring class. */
520
521         if (m->flags & ACC_STATIC) {
522                 /* For static methods we reset the object. */
523
524                 if (o != NULL)
525                         o = NULL;
526
527                 /* for convenience */
528
529                 resm = m;
530         }
531         else {
532                 /* For instance methods we make a virtual function table lookup. */
533
534                 resm = method_vftbl_lookup(vftbl, m);
535         }
536
537         STATISTICS(jnicallXmethodnvokation());
538
539         l = vm_call_method_long_jvalue(resm, o, args);
540
541         return l;
542 }
543
544
545 /* _Jv_jni_CallFloatMethod *****************************************************
546
547    Internal function to call Java float methods.
548
549 *******************************************************************************/
550
551 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
552                                                                           methodinfo *m, va_list ap)
553 {
554         methodinfo *resm;
555         jfloat      f;
556
557         /* Class initialization is done by the JIT compiler.  This is ok
558            since a static method always belongs to the declaring class. */
559
560         if (m->flags & ACC_STATIC) {
561                 /* For static methods we reset the object. */
562
563                 if (o != NULL)
564                         o = NULL;
565
566                 /* for convenience */
567
568                 resm = m;
569
570         } else {
571                 /* For instance methods we make a virtual function table lookup. */
572
573                 resm = method_vftbl_lookup(vftbl, m);
574         }
575
576         STATISTICS(jnicallXmethodnvokation());
577
578         f = vm_call_method_float_valist(resm, o, ap);
579
580         return f;
581 }
582
583
584 /* _Jv_jni_CallFloatMethodA ****************************************************
585
586    Internal function to call Java float methods.
587
588 *******************************************************************************/
589
590 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
591                                                                            methodinfo *m, const jvalue *args)
592 {
593         methodinfo *resm;
594         jfloat      f;
595
596         /* Class initialization is done by the JIT compiler.  This is ok
597            since a static method always belongs to the declaring class. */
598
599         if (m->flags & ACC_STATIC) {
600                 /* For static methods we reset the object. */
601
602                 if (o != NULL)
603                         o = NULL;
604
605                 /* for convenience */
606
607                 resm = m;
608         }
609         else {
610                 /* For instance methods we make a virtual function table lookup. */
611
612                 resm = method_vftbl_lookup(vftbl, m);
613         }
614
615         STATISTICS(jnicallXmethodnvokation());
616
617         f = vm_call_method_float_jvalue(resm, o, args);
618
619         return f;
620 }
621
622
623 /* _Jv_jni_CallDoubleMethod ****************************************************
624
625    Internal function to call Java double methods.
626
627 *******************************************************************************/
628
629 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
630                                                                                 methodinfo *m, va_list ap)
631 {
632         methodinfo *resm;
633         jdouble     d;
634
635         /* Class initialization is done by the JIT compiler.  This is ok
636            since a static method always belongs to the declaring class. */
637
638         if (m->flags & ACC_STATIC) {
639                 /* For static methods we reset the object. */
640
641                 if (o != NULL)
642                         o = NULL;
643
644                 /* for convenience */
645
646                 resm = m;
647
648         } else {
649                 /* For instance methods we make a virtual function table lookup. */
650
651                 resm = method_vftbl_lookup(vftbl, m);
652         }
653
654         d = vm_call_method_double_valist(resm, o, ap);
655
656         return d;
657 }
658
659
660 /* _Jv_jni_CallDoubleMethodA ***************************************************
661
662    Internal function to call Java double methods.
663
664 *******************************************************************************/
665
666 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
667                                                                                  methodinfo *m, const jvalue *args)
668 {
669         methodinfo *resm;
670         jdouble     d;
671
672         /* Class initialization is done by the JIT compiler.  This is ok
673            since a static method always belongs to the declaring class. */
674
675         if (m->flags & ACC_STATIC) {
676                 /* For static methods we reset the object. */
677
678                 if (o != NULL)
679                         o = NULL;
680
681                 /* for convenience */
682
683                 resm = m;
684         }
685         else {
686                 /* For instance methods we make a virtual function table lookup. */
687
688                 resm = method_vftbl_lookup(vftbl, m);
689         }
690
691         d = vm_call_method_double_jvalue(resm, o, args);
692
693         return d;
694 }
695
696
697 /* _Jv_jni_CallVoidMethod ******************************************************
698
699    Internal function to call Java void methods.
700
701 *******************************************************************************/
702
703 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
704                                                                    methodinfo *m, va_list ap)
705 {       
706         methodinfo *resm;
707
708         if (m == NULL) {
709                 exceptions_throw_nullpointerexception();
710                 return;
711         }
712
713         /* Class initialization is done by the JIT compiler.  This is ok
714            since a static method always belongs to the declaring class. */
715
716         if (m->flags & ACC_STATIC) {
717                 /* For static methods we reset the object. */
718
719                 if (o != NULL)
720                         o = NULL;
721
722                 /* for convenience */
723
724                 resm = m;
725
726         } else {
727                 /* For instance methods we make a virtual function table lookup. */
728
729                 resm = method_vftbl_lookup(vftbl, m);
730         }
731
732         STATISTICS(jnicallXmethodnvokation());
733
734         (void) vm_call_method_valist(resm, o, ap);
735 }
736
737
738 /* _Jv_jni_CallVoidMethodA *****************************************************
739
740    Internal function to call Java void methods.
741
742 *******************************************************************************/
743
744 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
745                                                                         methodinfo *m, const jvalue *args)
746 {       
747         methodinfo *resm;
748
749         if (m == NULL) {
750                 exceptions_throw_nullpointerexception();
751                 return;
752         }
753
754         /* Class initialization is done by the JIT compiler.  This is ok
755            since a static method always belongs to the declaring class. */
756
757         if (m->flags & ACC_STATIC) {
758                 /* For static methods we reset the object. */
759
760                 if (o != NULL)
761                         o = NULL;
762
763                 /* for convenience */
764
765                 resm = m;
766
767         } else {
768                 /* For instance methods we make a virtual function table lookup. */
769
770                 resm = method_vftbl_lookup(vftbl, m);
771         }
772
773         STATISTICS(jnicallXmethodnvokation());
774
775         (void) vm_call_method_jvalue(resm, o, args);
776 }
777
778
779 /* _Jv_jni_invokeNative ********************************************************
780
781    Invoke a method on the given object with the given arguments.
782
783    For instance methods OBJ must be != NULL and the method is looked up
784    in the vftbl of the object.
785
786    For static methods, OBJ is ignored.
787
788 *******************************************************************************/
789
790 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
791                                                                         java_handle_objectarray_t *params)
792 {
793         methodinfo    *resm;
794         java_handle_t *ro;
795         s4             argcount;
796         s4             paramcount;
797         java_handle_t *xptr;
798         int32_t        dumpsize;
799         uint64_t      *array;
800         imm_union          value;
801
802         if (m == NULL) {
803                 exceptions_throw_nullpointerexception();
804                 return NULL;
805         }
806
807         argcount = m->parseddesc->paramcount;
808         paramcount = argcount;
809
810         /* if method is non-static, remove the `this' pointer */
811
812         if (!(m->flags & ACC_STATIC))
813                 paramcount--;
814
815         /* For instance methods the object has to be an instance of the
816            class the method belongs to. For static methods the obj
817            parameter is ignored. */
818
819         if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
820                 exceptions_throw_illegalargumentexception();
821                 return NULL;
822         }
823
824         /* check if we got the right number of arguments */
825
826         if (((params == NULL) && (paramcount != 0)) ||
827                 (params && (LLNI_array_size(params) != paramcount))) 
828         {
829                 exceptions_throw_illegalargumentexception();
830                 return NULL;
831         }
832
833         /* for instance methods we need an object */
834
835         if (!(m->flags & ACC_STATIC) && (o == NULL)) {
836                 /* XXX not sure if that is the correct exception */
837                 exceptions_throw_nullpointerexception();
838                 return NULL;
839         }
840
841         /* for static methods, zero object to make subsequent code simpler */
842         if (m->flags & ACC_STATIC)
843                 o = NULL;
844
845         if (o != NULL) {
846                 /* for instance methods we must do a vftbl lookup */
847                 resm = method_vftbl_lookup(o->vftbl, m);
848         }
849         else {
850                 /* for static methods, just for convenience */
851                 resm = m;
852         }
853
854         /* mark start of dump memory area */
855
856         dumpsize = dump_size();
857
858         /* Fill the argument array from a object-array. */
859
860         array = vm_array_from_objectarray(resm, o, params);
861
862         /* The array can be NULL if we don't have any arguments to pass
863            and the architecture does not have any argument registers
864            (e.g. i386).  In that case we additionally check for an
865            exception thrown. */
866
867         if ((array == NULL) && (exceptions_get_exception() != NULL)) {
868                 /* release dump area */
869
870                 dump_release(dumpsize);
871
872                 return NULL;
873         }
874
875         switch (resm->parseddesc->returntype.decltype) {
876         case TYPE_VOID:
877                 (void) vm_call_array(resm, array);
878                 ro = NULL;
879                 break;
880
881         case PRIMITIVETYPE_BOOLEAN:
882         case PRIMITIVETYPE_BYTE:
883         case PRIMITIVETYPE_CHAR:
884         case PRIMITIVETYPE_SHORT:
885         case PRIMITIVETYPE_INT:
886                 value.i = vm_call_int_array(resm, array);
887                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
888                 break;
889
890         case PRIMITIVETYPE_LONG:
891                 value.l = vm_call_long_array(resm, array);
892                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
893                 break;
894
895         case PRIMITIVETYPE_FLOAT:
896                 value.f = vm_call_float_array(resm, array);
897                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
898                 break;
899
900         case PRIMITIVETYPE_DOUBLE:
901                 value.d = vm_call_double_array(resm, array);
902                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
903                 break;
904
905         case TYPE_ADR:
906                 ro = vm_call_array(resm, array);
907                 break;
908
909         default:
910                 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
911         }
912
913         xptr = exceptions_get_exception();
914
915         if (xptr != NULL) {
916                 /* clear exception pointer, we are calling JIT code again */
917
918                 exceptions_clear_exception();
919
920                 exceptions_throw_invocationtargetexception(xptr);
921         }
922
923         /* release dump area */
924
925         dump_release(dumpsize);
926
927         return ro;
928 }
929
930
931 /* GetVersion ******************************************************************
932
933    Returns the major version number in the higher 16 bits and the
934    minor version number in the lower 16 bits.
935
936 *******************************************************************************/
937
938 jint _Jv_JNI_GetVersion(JNIEnv *env)
939 {
940         STATISTICS(jniinvokation());
941
942         /* we support JNI 1.4 */
943
944         return JNI_VERSION_1_4;
945 }
946
947
948 /* Class Operations ***********************************************************/
949
950 /* DefineClass *****************************************************************
951
952    Loads a class from a buffer of raw class data. The buffer
953    containing the raw class data is not referenced by the VM after the
954    DefineClass call returns, and it may be discarded if desired.
955
956 *******************************************************************************/
957
958 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
959                                                    const jbyte *buf, jsize bufLen)
960 {
961 #if defined(ENABLE_JAVASE)
962         utf         *u;
963         classloader *cl;
964         classinfo   *c;
965
966         TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
967
968         u  = utf_new_char(name);
969         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
970
971         c = class_define(u, cl, bufLen, (const uint8_t *) buf);
972
973         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
974 #else
975         vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
976
977         /* keep compiler happy */
978
979         return 0;
980 #endif
981 }
982
983
984 /* FindClass *******************************************************************
985
986    This function loads a locally-defined class. It searches the
987    directories and zip files specified by the CLASSPATH environment
988    variable for the class with the specified name.
989
990 *******************************************************************************/
991
992 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
993 {
994 #if defined(ENABLE_JAVASE)
995         utf       *u;
996         classinfo *cc;
997         classinfo *c;
998
999         STATISTICS(jniinvokation());
1000
1001         u = utf_new_char_classname((char *) name);
1002
1003         /* Check stacktrace for classloader, if one found use it,
1004            otherwise use the system classloader. */
1005
1006         /* Quote from the JNI documentation:
1007          
1008            In the Java 2 Platform, FindClass locates the class loader
1009            associated with the current native method.  If the native code
1010            belongs to a system class, no class loader will be
1011            involved. Otherwise, the proper class loader will be invoked to
1012            load and link the named class. When FindClass is called through
1013            the Invocation Interface, there is no current native method or
1014            its associated class loader. In that case, the result of
1015            ClassLoader.getBaseClassLoader is used." */
1016
1017         cc = stacktrace_getCurrentClass();
1018
1019         if (cc == NULL)
1020                 c = load_class_from_sysloader(u);
1021         else
1022                 c = load_class_from_classloader(u, cc->classloader);
1023
1024         if (c == NULL)
1025                 return NULL;
1026
1027         if (!link_class(c))
1028                 return NULL;
1029
1030         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1031 #else
1032         vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1033
1034         /* keep compiler happy */
1035
1036         return NULL;
1037 #endif
1038 }
1039   
1040
1041 /* GetSuperclass ***************************************************************
1042
1043    If clazz represents any class other than the class Object, then
1044    this function returns the object that represents the superclass of
1045    the class specified by clazz.
1046
1047 *******************************************************************************/
1048  
1049 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1050 {
1051         classinfo *c;
1052         classinfo *super;
1053
1054         TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1055
1056         c = (classinfo *) sub;
1057
1058         if (c == NULL)
1059                 return NULL;
1060
1061         super = class_get_superclass(c);
1062
1063         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
1064 }
1065   
1066  
1067 /* IsAssignableFrom ************************************************************
1068
1069    Determines whether an object of sub can be safely cast to sup.
1070
1071 *******************************************************************************/
1072
1073 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1074 {
1075         java_lang_Class *csup;
1076         java_lang_Class *csub;
1077
1078         csup = (java_lang_Class *) sup;
1079         csub = (java_lang_Class *) sub;
1080
1081         STATISTICS(jniinvokation());
1082
1083         return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1084 }
1085
1086
1087 /* Throw ***********************************************************************
1088
1089    Causes a java.lang.Throwable object to be thrown.
1090
1091 *******************************************************************************/
1092
1093 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1094 {
1095         java_handle_t *o;
1096
1097         STATISTICS(jniinvokation());
1098
1099         o = (java_handle_t *) obj;
1100
1101         exceptions_set_exception(o);
1102
1103         return JNI_OK;
1104 }
1105
1106
1107 /* ThrowNew ********************************************************************
1108
1109    Constructs an exception object from the specified class with the
1110    message specified by message and causes that exception to be
1111    thrown.
1112
1113 *******************************************************************************/
1114
1115 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1116 {
1117         classinfo     *c;
1118         java_handle_t *o;
1119         java_handle_t *s;
1120
1121         STATISTICS(jniinvokation());
1122
1123         c = (classinfo *) clazz;
1124         if (msg == NULL)
1125                 msg = "";
1126         s = javastring_new_from_utf_string(msg);
1127
1128         /* instantiate exception object */
1129
1130         o = native_new_and_init_string(c, s);
1131
1132         if (o == NULL)
1133                 return -1;
1134
1135         exceptions_set_exception(o);
1136
1137         return 0;
1138 }
1139
1140
1141 /* ExceptionOccurred ***********************************************************
1142
1143    Determines if an exception is being thrown. The exception stays
1144    being thrown until either the native code calls ExceptionClear(),
1145    or the Java code handles the exception.
1146
1147 *******************************************************************************/
1148
1149 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1150 {
1151         java_handle_t *o;
1152
1153         STATISTICS(jniinvokation());
1154
1155         o = exceptions_get_exception();
1156
1157         return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1158 }
1159
1160
1161 /* ExceptionDescribe ***********************************************************
1162
1163    Prints an exception and a backtrace of the stack to a system
1164    error-reporting channel, such as stderr. This is a convenience
1165    routine provided for debugging.
1166
1167 *******************************************************************************/
1168
1169 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1170 {
1171         java_handle_t *o;
1172         methodinfo    *m;
1173
1174         STATISTICS(jniinvokation());
1175
1176         o = exceptions_get_exception();
1177
1178         if (o == NULL) {
1179                 /* clear exception, because we are calling jit code again */
1180
1181                 exceptions_clear_exception();
1182
1183                 /* get printStackTrace method from exception class */
1184
1185                 m = class_resolveclassmethod(o->vftbl->class,
1186                                                                          utf_printStackTrace,
1187                                                                          utf_void__void,
1188                                                                          NULL,
1189                                                                          true);
1190
1191                 if (m == NULL)
1192                         /* XXX what should we do? */
1193                         return;
1194
1195                 /* print the stacktrace */
1196
1197                 (void) vm_call_method(m, o);
1198         }
1199 }
1200
1201
1202 /* ExceptionClear **************************************************************
1203
1204    Clears any exception that is currently being thrown. If no
1205    exception is currently being thrown, this routine has no effect.
1206
1207 *******************************************************************************/
1208
1209 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1210 {
1211         STATISTICS(jniinvokation());
1212
1213         exceptions_clear_exception();
1214 }
1215
1216
1217 /* FatalError ******************************************************************
1218
1219    Raises a fatal error and does not expect the VM to recover. This
1220    function does not return.
1221
1222 *******************************************************************************/
1223
1224 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1225 {
1226         STATISTICS(jniinvokation());
1227
1228         /* this seems to be the best way */
1229
1230         vm_abort("JNI Fatal error: %s", msg);
1231 }
1232
1233
1234 /* PushLocalFrame **************************************************************
1235
1236    Creates a new local reference frame, in which at least a given
1237    number of local references can be created.
1238
1239 *******************************************************************************/
1240
1241 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1242 {
1243         STATISTICS(jniinvokation());
1244
1245         if (capacity <= 0)
1246                 return -1;
1247
1248         /* add new local reference frame to current table */
1249
1250         if (!localref_frame_push(capacity))
1251                 return -1;
1252
1253         return 0;
1254 }
1255
1256
1257 /* PopLocalFrame ***************************************************************
1258
1259    Pops off the current local reference frame, frees all the local
1260    references, and returns a local reference in the previous local
1261    reference frame for the given result object.
1262
1263 *******************************************************************************/
1264
1265 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1266 {
1267         STATISTICS(jniinvokation());
1268
1269         /* release all current local frames */
1270
1271         localref_frame_pop_all();
1272
1273         /* add local reference and return the value */
1274
1275         return _Jv_JNI_NewLocalRef(env, result);
1276 }
1277
1278
1279 /* DeleteLocalRef **************************************************************
1280
1281    Deletes the local reference pointed to by localRef.
1282
1283 *******************************************************************************/
1284
1285 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1286 {
1287         java_handle_t  *o;
1288         localref_table *lrt;
1289         s4              i;
1290
1291         STATISTICS(jniinvokation());
1292
1293         o = (java_handle_t *) localRef;
1294
1295         /* get local reference table (thread specific) */
1296
1297         lrt = LOCALREFTABLE;
1298
1299         /* go through all local frames */
1300
1301         for (; lrt != NULL; lrt = lrt->prev) {
1302
1303                 /* and try to remove the reference */
1304
1305                 for (i = 0; i < lrt->capacity; i++) {
1306                         if (lrt->refs[i] == o) {
1307                                 lrt->refs[i] = NULL;
1308                                 lrt->used--;
1309
1310                                 return;
1311                         }
1312                 }
1313         }
1314
1315         /* this should not happen */
1316
1317 /*      if (opt_checkjni) */
1318 /*      FatalError(env, "Bad global or local ref passed to JNI"); */
1319         log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1320 }
1321
1322
1323 /* IsSameObject ****************************************************************
1324
1325    Tests whether two references refer to the same Java object.
1326
1327 *******************************************************************************/
1328
1329 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1330 {
1331         STATISTICS(jniinvokation());
1332
1333         if (ref1 == ref2)
1334                 return JNI_TRUE;
1335         else
1336                 return JNI_FALSE;
1337 }
1338
1339
1340 /* NewLocalRef *****************************************************************
1341
1342    Creates a new local reference that refers to the same object as ref.
1343
1344 *******************************************************************************/
1345
1346 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1347 {
1348         localref_table *lrt;
1349         s4              i;
1350
1351         STATISTICS(jniinvokation());
1352
1353         if (ref == NULL)
1354                 return NULL;
1355
1356         /* get local reference table (thread specific) */
1357
1358         lrt = LOCALREFTABLE;
1359
1360         /* Check if we have space for the requested reference?  No,
1361            allocate a new frame.  This is actually not what the spec says,
1362            but for compatibility reasons... */
1363
1364         if (lrt->used == lrt->capacity) {
1365                 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1366                         return NULL;
1367
1368                 /* get the new local reference table */
1369
1370                 lrt = LOCALREFTABLE;
1371         }
1372
1373         /* insert the reference */
1374
1375         for (i = 0; i < lrt->capacity; i++) {
1376                 if (lrt->refs[i] == NULL) {
1377                         lrt->refs[i] = (java_handle_t *) ref;
1378                         lrt->used++;
1379
1380                         return ref;
1381                 }
1382         }
1383
1384         /* should not happen, just to be sure */
1385
1386         assert(0);
1387
1388         /* keep compiler happy */
1389
1390         return NULL;
1391 }
1392
1393
1394 /* EnsureLocalCapacity *********************************************************
1395
1396    Ensures that at least a given number of local references can be
1397    created in the current thread
1398
1399 *******************************************************************************/
1400
1401 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1402 {
1403         localref_table *lrt;
1404
1405         STATISTICS(jniinvokation());
1406
1407         /* get local reference table (thread specific) */
1408
1409         lrt = LOCALREFTABLE;
1410
1411         /* check if capacity elements are available in the local references table */
1412
1413         if ((lrt->used + capacity) > lrt->capacity)
1414                 return _Jv_JNI_PushLocalFrame(env, capacity);
1415
1416         return 0;
1417 }
1418
1419
1420 /* AllocObject *****************************************************************
1421
1422    Allocates a new Java object without invoking any of the
1423    constructors for the object. Returns a reference to the object.
1424
1425 *******************************************************************************/
1426
1427 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1428 {
1429         classinfo     *c;
1430         java_handle_t *o;
1431
1432         STATISTICS(jniinvokation());
1433
1434         c = (classinfo *) clazz;
1435
1436         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1437                 exceptions_throw_instantiationexception(c);
1438                 return NULL;
1439         }
1440                 
1441         o = builtin_new(c);
1442
1443         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1444 }
1445
1446
1447 /* NewObject *******************************************************************
1448
1449    Programmers place all arguments that are to be passed to the
1450    constructor immediately following the methodID
1451    argument. NewObject() accepts these arguments and passes them to
1452    the Java method that the programmer wishes to invoke.
1453
1454 *******************************************************************************/
1455
1456 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1457 {
1458         java_handle_t *o;
1459         classinfo     *c;
1460         methodinfo    *m;
1461         va_list        ap;
1462
1463         STATISTICS(jniinvokation());
1464
1465         c = (classinfo *) clazz;
1466         m = (methodinfo *) methodID;
1467
1468         /* create object */
1469
1470         o = builtin_new(c);
1471         
1472         if (o == NULL)
1473                 return NULL;
1474
1475         /* call constructor */
1476
1477         va_start(ap, methodID);
1478         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1479         va_end(ap);
1480
1481         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1482 }
1483
1484
1485 /* NewObjectV ******************************************************************
1486
1487    Programmers place all arguments that are to be passed to the
1488    constructor in an args argument of type va_list that immediately
1489    follows the methodID argument. NewObjectV() accepts these
1490    arguments, and, in turn, passes them to the Java method that the
1491    programmer wishes to invoke.
1492
1493 *******************************************************************************/
1494
1495 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1496                                                    va_list args)
1497 {
1498         java_handle_t *o;
1499         classinfo     *c;
1500         methodinfo    *m;
1501
1502         STATISTICS(jniinvokation());
1503
1504         c = (classinfo *) clazz;
1505         m = (methodinfo *) methodID;
1506
1507         /* create object */
1508
1509         o = builtin_new(c);
1510         
1511         if (o == NULL)
1512                 return NULL;
1513
1514         /* call constructor */
1515
1516         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1517
1518         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1519 }
1520
1521
1522 /* NewObjectA ***************************************************************** 
1523
1524    Programmers place all arguments that are to be passed to the
1525    constructor in an args array of jvalues that immediately follows
1526    the methodID argument. NewObjectA() accepts the arguments in this
1527    array, and, in turn, passes them to the Java method that the
1528    programmer wishes to invoke.
1529
1530 *******************************************************************************/
1531
1532 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1533                                                    const jvalue *args)
1534 {
1535         java_handle_t *o;
1536         classinfo     *c;
1537         methodinfo    *m;
1538
1539         STATISTICS(jniinvokation());
1540
1541         c = (classinfo *) clazz;
1542         m = (methodinfo *) methodID;
1543
1544         /* create object */
1545
1546         o = builtin_new(c);
1547         
1548         if (o == NULL)
1549                 return NULL;
1550
1551         /* call constructor */
1552
1553         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1554
1555         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1556 }
1557
1558
1559 /* GetObjectClass **************************************************************
1560
1561  Returns the class of an object.
1562
1563 *******************************************************************************/
1564
1565 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1566 {
1567         java_handle_t *o;
1568         classinfo     *c;
1569
1570         STATISTICS(jniinvokation());
1571
1572         o = (java_handle_t *) obj;
1573
1574         if ((o == NULL) || (o->vftbl == NULL))
1575                 return NULL;
1576
1577         c = o->vftbl->class;
1578
1579         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1580 }
1581
1582
1583 /* IsInstanceOf ****************************************************************
1584
1585    Tests whether an object is an instance of a class.
1586
1587 *******************************************************************************/
1588
1589 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1590 {
1591         java_lang_Class  *c;
1592         java_lang_Object *o;
1593
1594         STATISTICS(jniinvokation());
1595
1596         c = (java_lang_Class *) clazz;
1597         o = (java_lang_Object *) obj;
1598
1599         return _Jv_java_lang_Class_isInstance(c, o);
1600 }
1601
1602
1603 /* Reflection Support *********************************************************/
1604
1605 /* FromReflectedMethod *********************************************************
1606
1607    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1608    object to a method ID.
1609   
1610 *******************************************************************************/
1611   
1612 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1613 {
1614 #if defined(ENABLE_JAVASE)
1615         java_handle_t *o;
1616         classinfo     *c;
1617         methodinfo    *m;
1618         s4             slot;
1619
1620         STATISTICS(jniinvokation());
1621
1622         o = (java_handle_t *) method;
1623
1624         if (o == NULL)
1625                 return NULL;
1626         
1627         if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1628                 java_lang_reflect_Method *rm;
1629
1630                 rm   = (java_lang_reflect_Method *) method;
1631                 LLNI_field_get_cls(rm, clazz, c);
1632                 LLNI_field_get_val(rm, slot , slot);
1633         }
1634         else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1635                 java_lang_reflect_Constructor *rc;
1636
1637                 rc   = (java_lang_reflect_Constructor *) method;
1638                 LLNI_field_get_cls(rc, clazz, c);
1639                 LLNI_field_get_val(rc, slot , slot);
1640         }
1641         else
1642                 return NULL;
1643
1644         m = &(c->methods[slot]);
1645
1646         return (jmethodID) m;
1647 #else
1648         vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1649
1650         /* keep compiler happy */
1651
1652         return NULL;
1653 #endif
1654 }
1655
1656
1657 /* FromReflectedField **********************************************************
1658
1659    Converts a java.lang.reflect.Field to a field ID.
1660
1661 *******************************************************************************/
1662  
1663 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1664 {
1665 #if defined(ENABLE_JAVASE)
1666         java_lang_reflect_Field *rf;
1667         classinfo               *c;
1668         fieldinfo               *f;
1669         int32_t                  slot;
1670
1671         STATISTICS(jniinvokation());
1672
1673         rf = (java_lang_reflect_Field *) field;
1674
1675         if (rf == NULL)
1676                 return NULL;
1677
1678         LLNI_field_get_cls(rf, clazz, c);
1679         LLNI_field_get_val(rf, slot , slot);
1680         f = &(c->fields[slot]);
1681
1682         return (jfieldID) f;
1683 #else
1684         vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1685
1686         /* keep compiler happy */
1687
1688         return NULL;
1689 #endif
1690 }
1691
1692
1693 /* ToReflectedMethod ***********************************************************
1694
1695    Converts a method ID derived from cls to an instance of the
1696    java.lang.reflect.Method class or to an instance of the
1697    java.lang.reflect.Constructor class.
1698
1699 *******************************************************************************/
1700
1701 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1702                                                                   jboolean isStatic)
1703 {
1704 #if defined(ENABLE_JAVASE)
1705         methodinfo                    *m;
1706         java_lang_reflect_Constructor *rc;
1707         java_lang_reflect_Method      *rm;
1708
1709         STATISTICS(jniinvokation());
1710
1711         m = (methodinfo *) methodID;
1712
1713         /* HotSpot does the same assert. */
1714
1715         assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1716
1717         if (m->name == utf_init) {
1718                 rc = reflect_constructor_new(m);
1719
1720                 return (jobject) rc;
1721         }
1722         else {
1723                 rm = reflect_method_new(m);
1724
1725                 return (jobject) rm;
1726         }
1727 #else
1728         vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1729
1730         /* keep compiler happy */
1731
1732         return NULL;
1733 #endif
1734 }
1735
1736
1737 /* ToReflectedField ************************************************************
1738
1739    Converts a field ID derived from cls to an instance of the
1740    java.lang.reflect.Field class.
1741
1742 *******************************************************************************/
1743
1744 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1745                                                                  jboolean isStatic)
1746 {
1747         STATISTICS(jniinvokation());
1748
1749         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1750
1751         return NULL;
1752 }
1753
1754
1755 /* Calling Instance Methods ***************************************************/
1756
1757 /* GetMethodID *****************************************************************
1758
1759    Returns the method ID for an instance (nonstatic) method of a class
1760    or interface. The method may be defined in one of the clazz's
1761    superclasses and inherited by clazz. The method is determined by
1762    its name and signature.
1763
1764    GetMethodID() causes an uninitialized class to be initialized.
1765
1766 *******************************************************************************/
1767
1768 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1769                                                           const char *sig)
1770 {
1771         classinfo  *c;
1772         utf        *uname;
1773         utf        *udesc;
1774         methodinfo *m;
1775
1776         STATISTICS(jniinvokation());
1777
1778         c = (classinfo *) clazz;
1779
1780         if (c == NULL)
1781                 return NULL;
1782
1783         if (!(c->state & CLASS_INITIALIZED))
1784                 if (!initialize_class(c))
1785                         return NULL;
1786
1787         /* try to get the method of the class or one of it's superclasses */
1788
1789         uname = utf_new_char((char *) name);
1790         udesc = utf_new_char((char *) sig);
1791
1792         m = class_resolvemethod(c, uname, udesc);
1793
1794         if ((m == NULL) || (m->flags & ACC_STATIC)) {
1795                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1796
1797                 return NULL;
1798         }
1799
1800         return (jmethodID) m;
1801 }
1802
1803
1804 /* JNI-functions for calling instance methods *********************************/
1805
1806 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
1807 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
1808                                                                 jmethodID methodID, ...)    \
1809 {                                                           \
1810         java_handle_t *o;                                       \
1811         methodinfo    *m;                                       \
1812         va_list        ap;                                      \
1813         type           ret;                                     \
1814                                                             \
1815         o = (java_handle_t *) obj;                              \
1816         m = (methodinfo *) methodID;                            \
1817                                                             \
1818         va_start(ap, methodID);                                 \
1819         ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
1820         va_end(ap);                                             \
1821                                                             \
1822         return ret;                                             \
1823 }
1824
1825 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1826 JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
1827 JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
1828 JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
1829 JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
1830 JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
1831 JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
1832 JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
1833
1834
1835 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
1836 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
1837                                                                  jmethodID methodID, va_list args) \
1838 {                                                                  \
1839         java_handle_t *o;                                              \
1840         methodinfo    *m;                                              \
1841         type           ret;                                            \
1842                                                                    \
1843         o = (java_handle_t *) obj;                                     \
1844         m = (methodinfo *) methodID;                                   \
1845                                                                    \
1846         ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args);      \
1847                                                                    \
1848         return ret;                                                    \
1849 }
1850
1851 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1852 JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
1853 JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
1854 JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
1855 JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
1856 JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
1857 JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
1858 JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
1859
1860
1861 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
1862 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
1863                                                                  jmethodID methodID,           \
1864                                                                  const jvalue *args)           \
1865 {                                                              \
1866         java_handle_t *o;                                          \
1867         methodinfo    *m;                                          \
1868         type           ret;                                        \
1869                                                                \
1870         o = (java_handle_t *) obj;                                 \
1871         m = (methodinfo *) methodID;                               \
1872                                                                \
1873         ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
1874                                                                \
1875         return ret;                                                \
1876 }
1877
1878 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1879 JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
1880 JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
1881 JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
1882 JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
1883 JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
1884 JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
1885 JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
1886
1887
1888 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1889                                                                  ...)
1890 {
1891         java_handle_t *o;
1892         methodinfo    *m;
1893         java_handle_t *ret;
1894         va_list        ap;
1895
1896         o = (java_handle_t *) obj;
1897         m = (methodinfo *) methodID;
1898
1899         va_start(ap, methodID);
1900         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1901         va_end(ap);
1902
1903         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1904 }
1905
1906
1907 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1908                                                                   va_list args)
1909 {
1910         java_handle_t *o;
1911         methodinfo    *m;
1912         java_handle_t *ret;
1913
1914         o = (java_handle_t *) obj;
1915         m = (methodinfo *) methodID;
1916
1917         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1918
1919         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1920 }
1921
1922
1923 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1924                                                                   const jvalue *args)
1925 {
1926         java_handle_t *o;
1927         methodinfo    *m;
1928         java_handle_t *ret;
1929
1930         o = (java_handle_t *) obj;
1931         m = (methodinfo *) methodID;
1932
1933         ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1934
1935         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1936 }
1937
1938
1939
1940 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1941 {
1942         java_handle_t *o;
1943         methodinfo    *m;
1944         va_list        ap;
1945
1946         o = (java_handle_t *) obj;
1947         m = (methodinfo *) methodID;
1948
1949         va_start(ap, methodID);
1950         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1951         va_end(ap);
1952 }
1953
1954
1955 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1956                                                          va_list args)
1957 {
1958         java_handle_t *o;
1959         methodinfo    *m;
1960
1961         o = (java_handle_t *) obj;
1962         m = (methodinfo *) methodID;
1963
1964         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1965 }
1966
1967
1968 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1969                                                          const jvalue *args)
1970 {
1971         java_handle_t *o;
1972         methodinfo    *m;
1973
1974         o = (java_handle_t *) obj;
1975         m = (methodinfo *) methodID;
1976
1977         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1978 }
1979
1980
1981
1982 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
1983 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
1984                                                                                   jclass clazz, jmethodID methodID, \
1985                                                                                   ...)                              \
1986 {                                                                           \
1987         java_handle_t *o;                                                       \
1988         classinfo     *c;                                                       \
1989         methodinfo    *m;                                                       \
1990         va_list        ap;                                                      \
1991         type           ret;                                                     \
1992                                                                             \
1993         o = (java_handle_t *) obj;                                              \
1994         c = (classinfo *) clazz;                                                \
1995         m = (methodinfo *) methodID;                                            \
1996                                                                             \
1997         va_start(ap, methodID);                                                 \
1998         ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
1999         va_end(ap);                                                             \
2000                                                                             \
2001         return ret;                                                             \
2002 }
2003
2004 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
2005 JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
2006 JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
2007 JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
2008 JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
2009 JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
2010 JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
2011 JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
2012
2013
2014 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
2015 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
2016                                                                                    jclass clazz, jmethodID methodID, \
2017                                                                                    va_list args)                     \
2018 {                                                                            \
2019         java_handle_t *o;                                                        \
2020         classinfo     *c;                                                        \
2021         methodinfo    *m;                                                        \
2022         type           ret;                                                      \
2023                                                                              \
2024         o = (java_handle_t *) obj;                                               \
2025         c = (classinfo *) clazz;                                                 \
2026         m = (methodinfo *) methodID;                                             \
2027                                                                              \
2028         ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
2029                                                                              \
2030         return ret;                                                              \
2031 }
2032
2033 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2034 JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
2035 JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
2036 JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
2037 JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
2038 JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
2039 JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
2040 JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
2041
2042
2043 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
2044 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
2045                                                                                    jclass clazz, jmethodID methodID, \
2046                                                                                    const jvalue *args)               \
2047 {                                                                            \
2048         log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
2049                                                                              \
2050         return 0;                                                                \
2051 }
2052
2053 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2054 JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
2055 JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
2056 JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
2057 JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
2058 JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
2059 JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
2060 JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
2061
2062 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2063                                                                                    jclass clazz, jmethodID methodID,
2064                                                                                    ...)
2065 {
2066         java_handle_t *o;
2067         classinfo     *c;
2068         methodinfo    *m;
2069         java_handle_t *r;
2070         va_list        ap;
2071
2072         o = (java_handle_t *) obj;
2073         c = (classinfo *) clazz;
2074         m = (methodinfo *) methodID;
2075
2076         va_start(ap, methodID);
2077         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2078         va_end(ap);
2079
2080         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2081 }
2082
2083
2084 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2085                                                                                         jclass clazz, jmethodID methodID,
2086                                                                                         va_list args)
2087 {
2088         java_handle_t *o;
2089         classinfo     *c;
2090         methodinfo    *m;
2091         java_handle_t *r;
2092
2093         o = (java_handle_t *) obj;
2094         c = (classinfo *) clazz;
2095         m = (methodinfo *) methodID;
2096
2097         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2098
2099         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2100 }
2101
2102
2103 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2104                                                                                         jclass clazz, jmethodID methodID,
2105                                                                                         const jvalue *args)
2106 {
2107         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2108
2109         return _Jv_JNI_NewLocalRef(env, NULL);
2110 }
2111
2112
2113 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2114                                                                           jmethodID methodID, ...)
2115 {
2116         java_handle_t *o;
2117         classinfo     *c;
2118         methodinfo    *m;
2119         va_list        ap;
2120
2121         o = (java_handle_t *) obj;
2122         c = (classinfo *) clazz;
2123         m = (methodinfo *) methodID;
2124
2125         va_start(ap, methodID);
2126         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2127         va_end(ap);
2128 }
2129
2130
2131 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2132                                                                            jmethodID methodID, va_list args)
2133 {
2134         java_handle_t *o;
2135         classinfo     *c;
2136         methodinfo    *m;
2137
2138         o = (java_handle_t *) obj;
2139         c = (classinfo *) clazz;
2140         m = (methodinfo *) methodID;
2141
2142         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2143 }
2144
2145
2146 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2147                                                                            jmethodID methodID, const jvalue * args)
2148 {       
2149         java_handle_t *o;
2150         classinfo     *c;
2151         methodinfo    *m;
2152
2153         o = (java_handle_t *) obj;
2154         c = (classinfo *) clazz;
2155         m = (methodinfo *) methodID;
2156
2157         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2158 }
2159
2160
2161 /* Accessing Fields of Objects ************************************************/
2162
2163 /* GetFieldID ******************************************************************
2164
2165    Returns the field ID for an instance (nonstatic) field of a
2166    class. The field is specified by its name and signature. The
2167    Get<type>Field and Set<type>Field families of accessor functions
2168    use field IDs to retrieve object fields.
2169
2170 *******************************************************************************/
2171
2172 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2173                                                         const char *sig)
2174 {
2175         classinfo *c;
2176         fieldinfo *f;
2177         utf       *uname;
2178         utf       *udesc;
2179
2180         STATISTICS(jniinvokation());
2181
2182         c = (classinfo *) clazz;
2183
2184         /* XXX NPE check? */
2185
2186         uname = utf_new_char((char *) name);
2187         udesc = utf_new_char((char *) sig);
2188
2189         f = class_findfield(c, uname, udesc); 
2190         
2191         if (f == NULL)
2192                 exceptions_throw_nosuchfielderror(c, uname);  
2193
2194         return (jfieldID) f;
2195 }
2196
2197
2198 /* Get<type>Field Routines *****************************************************
2199
2200    This family of accessor routines returns the value of an instance
2201    (nonstatic) field of an object. The field to access is specified by
2202    a field ID obtained by calling GetFieldID().
2203
2204 *******************************************************************************/
2205
2206 #define JNI_GET_FIELD(name, type, intern)                                 \
2207 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2208 {                                                                         \
2209         intern ret;                                                           \
2210                                                                           \
2211         STATISTICS(jniinvokation());                                          \
2212                                                                           \
2213         ret = GET_FIELD(obj, intern, fieldID);                                \
2214                                                                           \
2215         return (type) ret;                                                    \
2216 }
2217
2218 JNI_GET_FIELD(Boolean, jboolean, s4)
2219 JNI_GET_FIELD(Byte,    jbyte,    s4)
2220 JNI_GET_FIELD(Char,    jchar,    s4)
2221 JNI_GET_FIELD(Short,   jshort,   s4)
2222 JNI_GET_FIELD(Int,     jint,     s4)
2223 JNI_GET_FIELD(Long,    jlong,    s8)
2224 JNI_GET_FIELD(Float,   jfloat,   float)
2225 JNI_GET_FIELD(Double,  jdouble,  double)
2226
2227
2228 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2229 {
2230         java_handle_t *o;
2231
2232         STATISTICS(jniinvokation());
2233
2234 #warning this needs to be fixed
2235         o = GET_FIELD(obj, java_handle_t*, fieldID);
2236
2237         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2238 }
2239
2240
2241 /* Set<type>Field Routines *****************************************************
2242
2243    This family of accessor routines sets the value of an instance
2244    (nonstatic) field of an object. The field to access is specified by
2245    a field ID obtained by calling GetFieldID().
2246
2247 *******************************************************************************/
2248
2249 #define JNI_SET_FIELD(name, type, intern)                                 \
2250 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2251                                                           type value)                                 \
2252 {                                                                         \
2253         STATISTICS(jniinvokation());                                          \
2254                                                                           \
2255         SET_FIELD(obj, intern, fieldID, value);                               \
2256 }
2257
2258 JNI_SET_FIELD(Boolean, jboolean, s4)
2259 JNI_SET_FIELD(Byte,    jbyte,    s4)
2260 JNI_SET_FIELD(Char,    jchar,    s4)
2261 JNI_SET_FIELD(Short,   jshort,   s4)
2262 JNI_SET_FIELD(Int,     jint,     s4)
2263 JNI_SET_FIELD(Long,    jlong,    s8)
2264 JNI_SET_FIELD(Float,   jfloat,   float)
2265 JNI_SET_FIELD(Double,  jdouble,  double)
2266
2267
2268 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2269                                                         jobject value)
2270 {
2271         STATISTICS(jniinvokation());
2272
2273 #warning this needs to be fixed
2274         SET_FIELD(obj, java_handle_t*, fieldID, value);
2275 }
2276
2277
2278 /* Calling Static Methods *****************************************************/
2279
2280 /* GetStaticMethodID ***********************************************************
2281
2282    Returns the method ID for a static method of a class. The method is
2283    specified by its name and signature.
2284
2285    GetStaticMethodID() causes an uninitialized class to be
2286    initialized.
2287
2288 *******************************************************************************/
2289
2290 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2291                                                                         const char *sig)
2292 {
2293         classinfo  *c;
2294         utf        *uname;
2295         utf        *udesc;
2296         methodinfo *m;
2297
2298         STATISTICS(jniinvokation());
2299
2300         c = (classinfo *) clazz;
2301
2302         if (!c)
2303                 return NULL;
2304
2305         if (!(c->state & CLASS_INITIALIZED))
2306                 if (!initialize_class(c))
2307                         return NULL;
2308
2309         /* try to get the static method of the class */
2310
2311         uname = utf_new_char((char *) name);
2312         udesc = utf_new_char((char *) sig);
2313
2314         m = class_resolvemethod(c, uname, udesc);
2315
2316         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2317                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2318
2319                 return NULL;
2320         }
2321
2322         return (jmethodID) m;
2323 }
2324
2325
2326 #define JNI_CALL_STATIC_METHOD(name, type, intern)               \
2327 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2328                                                                           jmethodID methodID, ...)   \
2329 {                                                                \
2330         methodinfo *m;                                               \
2331         va_list     ap;                                              \
2332         type        res;                                             \
2333                                                                  \
2334         m = (methodinfo *) methodID;                                 \
2335                                                                  \
2336         va_start(ap, methodID);                                      \
2337         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
2338         va_end(ap);                                                  \
2339                                                                  \
2340         return res;                                                  \
2341 }
2342
2343 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2344 JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
2345 JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
2346 JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
2347 JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
2348 JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
2349 JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
2350 JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
2351
2352
2353 #define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
2354 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
2355                                                                            jmethodID methodID, va_list args) \
2356 {                                                                        \
2357         methodinfo *m;                                                       \
2358         type        res;                                                     \
2359                                                                          \
2360         m = (methodinfo *) methodID;                                         \
2361                                                                          \
2362         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
2363                                                                          \
2364         return res;                                                          \
2365 }
2366
2367 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2368 JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
2369 JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
2370 JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
2371 JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
2372 JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
2373 JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
2374 JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
2375
2376
2377 #define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
2378 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
2379                                                                            jmethodID methodID, const jvalue *args) \
2380 {                                                                              \
2381         methodinfo *m;                                                             \
2382         type        res;                                                           \
2383                                                                                \
2384         m = (methodinfo *) methodID;                                               \
2385                                                                                \
2386         res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
2387                                                                                \
2388         return res;                                                                \
2389 }
2390
2391 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2392 JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
2393 JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
2394 JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
2395 JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
2396 JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
2397 JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
2398 JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
2399
2400
2401 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2402                                                                            jmethodID methodID, ...)
2403 {
2404         methodinfo    *m;
2405         java_handle_t *o;
2406         va_list        ap;
2407
2408         m = (methodinfo *) methodID;
2409
2410         va_start(ap, methodID);
2411         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2412         va_end(ap);
2413
2414         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2415 }
2416
2417
2418 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2419                                                                                 jmethodID methodID, va_list args)
2420 {
2421         methodinfo    *m;
2422         java_handle_t *o;
2423
2424         m = (methodinfo *) methodID;
2425
2426         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2427
2428         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2429 }
2430
2431
2432 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2433                                                                                 jmethodID methodID, const jvalue *args)
2434 {
2435         methodinfo    *m;
2436         java_handle_t *o;
2437
2438         m = (methodinfo *) methodID;
2439
2440         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2441
2442         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2443 }
2444
2445
2446 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2447                                                                   jmethodID methodID, ...)
2448 {
2449         methodinfo *m;
2450         va_list     ap;
2451
2452         m = (methodinfo *) methodID;
2453
2454         va_start(ap, methodID);
2455         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2456         va_end(ap);
2457 }
2458
2459
2460 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2461                                                                    jmethodID methodID, va_list args)
2462 {
2463         methodinfo *m;
2464
2465         m = (methodinfo *) methodID;
2466
2467         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2468 }
2469
2470
2471 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2472                                                                    jmethodID methodID, const jvalue * args)
2473 {
2474         methodinfo *m;
2475
2476         m = (methodinfo *) methodID;
2477
2478         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2479 }
2480
2481
2482 /* Accessing Static Fields ****************************************************/
2483
2484 /* GetStaticFieldID ************************************************************
2485
2486    Returns the field ID for a static field of a class. The field is
2487    specified by its name and signature. The GetStatic<type>Field and
2488    SetStatic<type>Field families of accessor functions use field IDs
2489    to retrieve static fields.
2490
2491 *******************************************************************************/
2492
2493 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2494                                                                   const char *sig)
2495 {
2496         classinfo *c;
2497         fieldinfo *f;
2498         utf       *uname;
2499         utf       *usig;
2500
2501         STATISTICS(jniinvokation());
2502
2503         c = (classinfo *) clazz;
2504
2505         uname = utf_new_char((char *) name);
2506         usig  = utf_new_char((char *) sig);
2507
2508         f = class_findfield(c, uname, usig);
2509         
2510         if (f == NULL)
2511                 exceptions_throw_nosuchfielderror(c, uname);
2512
2513         return (jfieldID) f;
2514 }
2515
2516
2517 /* GetStatic<type>Field ********************************************************
2518
2519    This family of accessor routines returns the value of a static
2520    field of an object.
2521
2522 *******************************************************************************/
2523
2524 #define JNI_GET_STATIC_FIELD(name, type, field)                \
2525 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2526                                                                         jfieldID fieldID)          \
2527 {                                                              \
2528         classinfo *c;                                              \
2529         fieldinfo *f;                                              \
2530                                                                \
2531         STATISTICS(jniinvokation());                               \
2532                                                                \
2533         c = (classinfo *) clazz;                                   \
2534         f = (fieldinfo *) fieldID;                                 \
2535                                                                \
2536         if (!(c->state & CLASS_INITIALIZED))                       \
2537                 if (!initialize_class(c))                              \
2538                         return 0;                                          \
2539                                                                \
2540         return f->value->field;                                    \
2541 }
2542
2543 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2544 JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
2545 JNI_GET_STATIC_FIELD(Char,    jchar,    i)
2546 JNI_GET_STATIC_FIELD(Short,   jshort,   i)
2547 JNI_GET_STATIC_FIELD(Int,     jint,     i)
2548 JNI_GET_STATIC_FIELD(Long,    jlong,    l)
2549 JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
2550 JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
2551
2552
2553 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2554                                                                          jfieldID fieldID)
2555 {
2556         classinfo *c;
2557         fieldinfo *f;
2558
2559         STATISTICS(jniinvokation());
2560
2561         c = (classinfo *) clazz;
2562         f = (fieldinfo *) fieldID;
2563
2564         if (!(c->state & CLASS_INITIALIZED))
2565                 if (!initialize_class(c))
2566                         return NULL;
2567
2568         return _Jv_JNI_NewLocalRef(env, f->value->a);
2569 }
2570
2571
2572 /*  SetStatic<type>Field *******************************************************
2573
2574         This family of accessor routines sets the value of a static field
2575         of an object.
2576
2577 *******************************************************************************/
2578
2579 #define JNI_SET_STATIC_FIELD(name, type, field)                \
2580 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2581                                                                         jfieldID fieldID,          \
2582                                                                         type value)                \
2583 {                                                              \
2584         classinfo *c;                                              \
2585         fieldinfo *f;                                              \
2586                                                                \
2587         STATISTICS(jniinvokation());                               \
2588                                                                \
2589         c = (classinfo *) clazz;                                   \
2590         f = (fieldinfo *) fieldID;                                 \
2591                                                                \
2592         if (!(c->state & CLASS_INITIALIZED))                       \
2593                 if (!initialize_class(c))                              \
2594                         return;                                            \
2595                                                                \
2596         f->value->field = value;                                   \
2597 }
2598
2599 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2600 JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
2601 JNI_SET_STATIC_FIELD(Char,    jchar,    i)
2602 JNI_SET_STATIC_FIELD(Short,   jshort,   i)
2603 JNI_SET_STATIC_FIELD(Int,     jint,     i)
2604 JNI_SET_STATIC_FIELD(Long,    jlong,    l)
2605 JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
2606 JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
2607
2608
2609 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2610                                                                   jobject value)
2611 {
2612         classinfo *c;
2613         fieldinfo *f;
2614
2615         STATISTICS(jniinvokation());
2616
2617         c = (classinfo *) clazz;
2618         f = (fieldinfo *) fieldID;
2619
2620         if (!(c->state & CLASS_INITIALIZED))
2621                 if (!initialize_class(c))
2622                         return;
2623
2624         f->value->a = value;
2625 }
2626
2627
2628 /* String Operations **********************************************************/
2629
2630 /* NewString *******************************************************************
2631
2632    Create new java.lang.String object from an array of Unicode
2633    characters.
2634
2635 *******************************************************************************/
2636
2637 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2638 {
2639         java_lang_String        *s;
2640         java_handle_chararray_t *a;
2641         u4                       i;
2642
2643         STATISTICS(jniinvokation());
2644         
2645         s = (java_lang_String *) builtin_new(class_java_lang_String);
2646         a = builtin_newarray_char(len);
2647
2648         /* javastring or characterarray could not be created */
2649         if ((a == NULL) || (s == NULL))
2650                 return NULL;
2651
2652         /* copy text */
2653         for (i = 0; i < len; i++)
2654                 LLNI_array_direct(a, i) = buf[i];
2655
2656         LLNI_field_set_ref(s, value , a);
2657         LLNI_field_set_val(s, offset, 0);
2658         LLNI_field_set_val(s, count , len);
2659
2660         return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2661 }
2662
2663
2664 static jchar emptyStringJ[]={0,0};
2665
2666 /* GetStringLength *************************************************************
2667
2668    Returns the length (the count of Unicode characters) of a Java
2669    string.
2670
2671 *******************************************************************************/
2672
2673 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2674 {
2675         java_lang_String *s;
2676         jsize             len;
2677
2678         TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2679
2680         s = (java_lang_String *) str;
2681
2682         LLNI_field_get_val(s, count, len);
2683
2684         return len;
2685 }
2686
2687
2688 /********************  convertes javastring to u2-array ****************************/
2689         
2690 u2 *javastring_tou2(jstring so) 
2691 {
2692         java_lang_String        *s;
2693         java_handle_chararray_t *a;
2694         u2                      *stringbuffer;
2695         u4                       i;
2696         int32_t                  count;
2697         int32_t                  offset;
2698
2699         STATISTICS(jniinvokation());
2700         
2701         s = (java_lang_String *) so;
2702
2703         if (!s)
2704                 return NULL;
2705
2706         LLNI_field_get_ref(s, value, a);
2707
2708         if (!a)
2709                 return NULL;
2710
2711         LLNI_field_get_val(s, count, count);
2712         LLNI_field_get_val(s, offset, offset);
2713
2714         /* allocate memory */
2715
2716         stringbuffer = MNEW(u2, count + 1);
2717
2718         /* copy text */
2719
2720         for (i = 0; i < count; i++)
2721                 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2722         
2723         /* terminate string */
2724
2725         stringbuffer[i] = '\0';
2726
2727         return stringbuffer;
2728 }
2729
2730
2731 /* GetStringChars **************************************************************
2732
2733    Returns a pointer to the array of Unicode characters of the
2734    string. This pointer is valid until ReleaseStringChars() is called.
2735
2736 *******************************************************************************/
2737
2738 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2739 {       
2740         jchar *jc;
2741
2742         STATISTICS(jniinvokation());
2743
2744         jc = javastring_tou2(str);
2745
2746         if (jc) {
2747                 if (isCopy)
2748                         *isCopy = JNI_TRUE;
2749
2750                 return jc;
2751         }
2752
2753         if (isCopy)
2754                 *isCopy = JNI_TRUE;
2755
2756         return emptyStringJ;
2757 }
2758
2759
2760 /* ReleaseStringChars **********************************************************
2761
2762    Informs the VM that the native code no longer needs access to
2763    chars. The chars argument is a pointer obtained from string using
2764    GetStringChars().
2765
2766 *******************************************************************************/
2767
2768 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2769 {
2770         java_lang_String *s;
2771
2772         STATISTICS(jniinvokation());
2773
2774         if (chars == emptyStringJ)
2775                 return;
2776
2777         s = (java_lang_String *) str;
2778
2779         MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2780 }
2781
2782
2783 /* NewStringUTF ****************************************************************
2784
2785    Constructs a new java.lang.String object from an array of UTF-8
2786    characters.
2787
2788 *******************************************************************************/
2789
2790 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2791 {
2792         java_lang_String *s;
2793
2794         TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2795
2796         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2797
2798     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2799 }
2800
2801
2802 /****************** returns the utf8 length in bytes of a string *******************/
2803
2804 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2805 {   
2806         java_lang_String *s;
2807         s4                length;
2808
2809         TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2810
2811         s = (java_lang_String *) string;
2812
2813         length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2814
2815         return length;
2816 }
2817
2818
2819 /* GetStringUTFChars ***********************************************************
2820
2821    Returns a pointer to an array of UTF-8 characters of the
2822    string. This array is valid until it is released by
2823    ReleaseStringUTFChars().
2824
2825 *******************************************************************************/
2826
2827 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2828                                                                           jboolean *isCopy)
2829 {
2830         utf *u;
2831
2832         STATISTICS(jniinvokation());
2833
2834         if (string == NULL)
2835                 return "";
2836
2837         if (isCopy)
2838                 *isCopy = JNI_TRUE;
2839         
2840         u = javastring_toutf((java_handle_t *) string, false);
2841
2842         if (u != NULL)
2843                 return u->text;
2844
2845         return "";
2846 }
2847
2848
2849 /* ReleaseStringUTFChars *******************************************************
2850
2851    Informs the VM that the native code no longer needs access to
2852    utf. The utf argument is a pointer derived from string using
2853    GetStringUTFChars().
2854
2855 *******************************************************************************/
2856
2857 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2858 {
2859         STATISTICS(jniinvokation());
2860
2861     /* XXX we don't release utf chars right now, perhaps that should be done 
2862            later. Since there is always one reference the garbage collector will
2863            never get them */
2864 }
2865
2866
2867 /* Array Operations ***********************************************************/
2868
2869 /* GetArrayLength **************************************************************
2870
2871    Returns the number of elements in the array.
2872
2873 *******************************************************************************/
2874
2875 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2876 {
2877         java_handle_t *a;
2878         jsize          size;
2879
2880         STATISTICS(jniinvokation());
2881
2882         a = (java_handle_t *) array;
2883
2884         size = LLNI_array_size(a);
2885
2886         return size;
2887 }
2888
2889
2890 /* NewObjectArray **************************************************************
2891
2892    Constructs a new array holding objects in class elementClass. All
2893    elements are initially set to initialElement.
2894
2895 *******************************************************************************/
2896
2897 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2898                                                                         jclass elementClass, jobject initialElement)
2899 {
2900         classinfo                 *c;
2901         java_handle_t             *o;
2902         java_handle_objectarray_t *oa;
2903         s4                         i;
2904
2905         STATISTICS(jniinvokation());
2906
2907         c = (classinfo *) elementClass;
2908         o = (java_handle_t *) initialElement;
2909
2910         if (length < 0) {
2911                 exceptions_throw_negativearraysizeexception();
2912                 return NULL;
2913         }
2914
2915     oa = builtin_anewarray(length, c);
2916
2917         if (oa == NULL)
2918                 return NULL;
2919
2920         /* set all elements to initialElement */
2921
2922         for (i = 0; i < length; i++)
2923                 LLNI_objectarray_element_set(oa, i, o);
2924
2925         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2926 }
2927
2928
2929 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2930                                                                           jsize index)
2931 {
2932         java_handle_objectarray_t *oa;
2933         java_handle_t             *o;
2934
2935         STATISTICS(jniinvokation());
2936
2937         oa = (java_handle_objectarray_t *) array;
2938
2939         if (index >= LLNI_array_size(oa)) {
2940                 exceptions_throw_arrayindexoutofboundsexception();
2941                 return NULL;
2942         }
2943
2944         LLNI_objectarray_element_get(oa, index, o);
2945
2946         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2947 }
2948
2949
2950 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2951                                                                    jsize index, jobject val)
2952 {
2953         java_handle_objectarray_t *oa;
2954         java_handle_t             *o;
2955
2956         STATISTICS(jniinvokation());
2957
2958         oa = (java_handle_objectarray_t *) array;
2959         o  = (java_handle_t *) val;
2960
2961         if (index >= LLNI_array_size(oa)) {
2962                 exceptions_throw_arrayindexoutofboundsexception();
2963                 return;
2964         }
2965
2966         /* check if the class of value is a subclass of the element class
2967            of the array */
2968
2969         if (!builtin_canstore(oa, o))
2970                 return;
2971
2972         LLNI_objectarray_element_set(oa, index, o);
2973 }
2974
2975
2976 #define JNI_NEW_ARRAY(name, type, intern)                \
2977 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
2978 {                                                        \
2979         java_handle_##intern##array_t *a;                    \
2980                                                          \
2981         STATISTICS(jniinvokation());                         \
2982                                                          \
2983         if (len < 0) {                                       \
2984                 exceptions_throw_negativearraysizeexception();   \
2985                 return NULL;                                     \
2986         }                                                    \
2987                                                          \
2988         a = builtin_newarray_##intern(len);                  \
2989                                                          \
2990         return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2991 }
2992
2993 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2994 JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
2995 JNI_NEW_ARRAY(Char,    jcharArray,    char)
2996 JNI_NEW_ARRAY(Short,   jshortArray,   byte)
2997 JNI_NEW_ARRAY(Int,     jintArray,     int)
2998 JNI_NEW_ARRAY(Long,    jlongArray,    long)
2999 JNI_NEW_ARRAY(Float,   jfloatArray,   float)
3000 JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
3001
3002
3003 /* Get<PrimitiveType>ArrayElements *********************************************
3004
3005    A family of functions that returns the body of the primitive array.
3006
3007 *******************************************************************************/
3008
3009 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
3010 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3011                                                                                  jboolean *isCopy)             \
3012 {                                                                      \
3013         java_handle_##intern##array_t *a;                                  \
3014                                                                        \
3015         STATISTICS(jniinvokation());                                       \
3016                                                                        \
3017         a = (java_handle_##intern##array_t *) array;                       \
3018                                                                        \
3019         if (isCopy)                                                        \
3020                 *isCopy = JNI_FALSE;                                           \
3021                                                                        \
3022         return LLNI_array_data(a);                                         \
3023 }
3024
3025 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3026 JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
3027 JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
3028 JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
3029 JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
3030 JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
3031 JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
3032 JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
3033
3034
3035 /* Release<PrimitiveType>ArrayElements *****************************************
3036
3037    A family of functions that informs the VM that the native code no
3038    longer needs access to elems. The elems argument is a pointer
3039    derived from array using the corresponding
3040    Get<PrimitiveType>ArrayElements() function. If necessary, this
3041    function copies back all changes made to elems to the original
3042    array.
3043
3044 *******************************************************************************/
3045
3046 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
3047 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
3048                                                                                   type *elems, jint mode)          \
3049 {                                                                          \
3050         java_handle_##intern##array_t *a;                                      \
3051                                                                            \
3052         STATISTICS(jniinvokation());                                           \
3053                                                                            \
3054         a = (java_handle_##intern##array_t *) array;                           \
3055                                                                            \
3056         if (elems != LLNI_array_data(a)) {                                     \
3057                 switch (mode) {                                                    \
3058                 case JNI_COMMIT:                                                   \
3059                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3060                         break;                                                         \
3061                 case 0:                                                            \
3062                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3063                         /* XXX TWISTI how should it be freed? */                       \
3064                         break;                                                         \
3065                 case JNI_ABORT:                                                    \
3066                         /* XXX TWISTI how should it be freed? */                       \
3067                         break;                                                         \
3068                 }                                                                  \
3069         }                                                                      \
3070 }
3071
3072 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3073 JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
3074 JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
3075 JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
3076 JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
3077 JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
3078 JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
3079 JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
3080
3081
3082 /*  Get<PrimitiveType>ArrayRegion **********************************************
3083
3084         A family of functions that copies a region of a primitive array
3085         into a buffer.
3086
3087 *******************************************************************************/
3088
3089 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
3090 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
3091                                                                         jsize start, jsize len, type *buf)  \
3092 {                                                                       \
3093         java_handle_##intern##array_t *a;                                   \
3094                                                                         \
3095         STATISTICS(jniinvokation());                                        \
3096                                                                         \
3097         a = (java_handle_##intern##array_t *) array;                        \
3098                                                                         \
3099         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3100                 exceptions_throw_arrayindexoutofboundsexception();              \
3101         else                                                                \
3102                 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
3103 }
3104
3105 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3106 JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3107 JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
3108 JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
3109 JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
3110 JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
3111 JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
3112 JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
3113
3114
3115 /*  Set<PrimitiveType>ArrayRegion **********************************************
3116
3117         A family of functions that copies back a region of a primitive
3118         array from a buffer.
3119
3120 *******************************************************************************/
3121
3122 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
3123 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
3124                                                                         jsize start, jsize len, const type *buf) \
3125 {                                                                            \
3126         java_handle_##intern##array_t *a;                                        \
3127                                                                              \
3128         STATISTICS(jniinvokation());                                             \
3129                                                                              \
3130         a = (java_handle_##intern##array_t *) array;                             \
3131                                                                              \
3132         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
3133                 exceptions_throw_arrayindexoutofboundsexception();                   \
3134         else                                                                     \
3135                 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
3136 }
3137
3138 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3139 JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3140 JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
3141 JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
3142 JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
3143 JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
3144 JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
3145 JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
3146
3147
3148 /* Registering Native Methods *************************************************/
3149
3150 /* RegisterNatives *************************************************************
3151
3152    Registers native methods with the class specified by the clazz
3153    argument. The methods parameter specifies an array of
3154    JNINativeMethod structures that contain the names, signatures, and
3155    function pointers of the native methods. The nMethods parameter
3156    specifies the number of native methods in the array.
3157
3158 *******************************************************************************/
3159
3160 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3161                                                          const JNINativeMethod *methods, jint nMethods)
3162 {
3163         classinfo *c;
3164
3165         STATISTICS(jniinvokation());
3166
3167         c = (classinfo *) clazz;
3168
3169         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3170         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
3171         */
3172
3173         native_method_register(c->name, methods, nMethods);
3174
3175     return 0;
3176 }
3177
3178
3179 /* UnregisterNatives ***********************************************************
3180
3181    Unregisters native methods of a class. The class goes back to the
3182    state before it was linked or registered with its native method
3183    functions.
3184
3185    This function should not be used in normal native code. Instead, it
3186    provides special programs a way to reload and relink native
3187    libraries.
3188
3189 *******************************************************************************/
3190
3191 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3192 {
3193         STATISTICS(jniinvokation());
3194
3195         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3196
3197     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3198
3199     return 0;
3200 }
3201
3202
3203 /* Monitor Operations *********************************************************/
3204
3205 /* MonitorEnter ****************************************************************
3206
3207    Enters the monitor associated with the underlying Java object
3208    referred to by obj.
3209
3210 *******************************************************************************/
3211
3212 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3213 {
3214         STATISTICS(jniinvokation());
3215
3216         if (obj == NULL) {
3217                 exceptions_throw_nullpointerexception();
3218                 return JNI_ERR;
3219         }
3220
3221         LOCK_MONITOR_ENTER(obj);
3222
3223         return JNI_OK;
3224 }
3225
3226
3227 /* MonitorExit *****************************************************************
3228
3229    The current thread must be the owner of the monitor associated with
3230    the underlying Java object referred to by obj. The thread
3231    decrements the counter indicating the number of times it has
3232    entered this monitor. If the value of the counter becomes zero, the
3233    current thread releases the monitor.
3234
3235 *******************************************************************************/
3236
3237 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3238 {
3239         STATISTICS(jniinvokation());
3240
3241         if (obj == NULL) {
3242                 exceptions_throw_nullpointerexception();
3243                 return JNI_ERR;
3244         }
3245
3246         LOCK_MONITOR_EXIT(obj);
3247
3248         return JNI_OK;
3249 }
3250
3251
3252 /* JavaVM Interface ***********************************************************/
3253
3254 /* GetJavaVM *******************************************************************
3255
3256    Returns the Java VM interface (used in the Invocation API)
3257    associated with the current thread. The result is placed at the
3258    location pointed to by the second argument, vm.
3259
3260 *******************************************************************************/
3261
3262 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3263 {
3264         STATISTICS(jniinvokation());
3265
3266     *vm = (JavaVM *) _Jv_jvm;
3267
3268         return 0;
3269 }
3270
3271
3272 /* GetStringRegion *************************************************************
3273
3274    Copies len number of Unicode characters beginning at offset start
3275    to the given buffer buf.
3276
3277    Throws StringIndexOutOfBoundsException on index overflow.
3278
3279 *******************************************************************************/
3280
3281 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3282                                                          jchar *buf)
3283 {
3284         java_lang_String        *s;
3285         java_handle_chararray_t *ca;
3286
3287         STATISTICS(jniinvokation());
3288
3289         s  = (java_lang_String *) str;
3290         LLNI_field_get_ref(s, value, ca);
3291
3292         if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3293                 (start + len > LLNI_field_direct(s, count))) {
3294                 exceptions_throw_stringindexoutofboundsexception();
3295                 return;
3296         }
3297
3298         MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3299 }
3300
3301
3302 /* GetStringUTFRegion **********************************************************
3303
3304     Translates len number of Unicode characters beginning at offset
3305     start into UTF-8 format and place the result in the given buffer
3306     buf.
3307
3308     Throws StringIndexOutOfBoundsException on index overflow. 
3309
3310 *******************************************************************************/
3311
3312 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3313                                                                 jsize len, char *buf)
3314 {
3315         java_lang_String        *s;
3316         java_handle_chararray_t *ca;
3317         s4                       i;
3318         int32_t                  count;
3319         int32_t                  offset;
3320
3321         TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3322
3323         s  = (java_lang_String *) str;
3324         LLNI_field_get_ref(s, value, ca);
3325         LLNI_field_get_val(s, count, count);
3326         LLNI_field_get_val(s, offset, offset);
3327
3328         if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3329                 exceptions_throw_stringindexoutofboundsexception();
3330                 return;
3331         }
3332
3333         for (i = 0; i < len; i++)
3334                 buf[i] = LLNI_array_direct(ca, offset + start + i);
3335
3336         buf[i] = '\0';
3337 }
3338
3339
3340 /* GetPrimitiveArrayCritical ***************************************************
3341
3342    Obtain a direct pointer to array elements.
3343
3344 *******************************************************************************/
3345
3346 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3347                                                                                 jboolean *isCopy)
3348 {
3349         java_handle_bytearray_t *ba;
3350         jbyte                   *bp;
3351
3352         ba = (java_handle_bytearray_t *) array;
3353
3354         /* do the same as Kaffe does */
3355
3356         bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3357
3358         return (void *) bp;
3359 }
3360
3361
3362 /* ReleasePrimitiveArrayCritical ***********************************************
3363
3364    No specific documentation.
3365
3366 *******************************************************************************/
3367
3368 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3369                                                                                    void *carray, jint mode)
3370 {
3371         STATISTICS(jniinvokation());
3372
3373         /* do the same as Kaffe does */
3374
3375         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3376                                                                          mode);
3377 }
3378
3379
3380 /* GetStringCritical ***********************************************************
3381
3382    The semantics of these two functions are similar to the existing
3383    Get/ReleaseStringChars functions.
3384
3385 *******************************************************************************/
3386
3387 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3388                                                                            jboolean *isCopy)
3389 {
3390         STATISTICS(jniinvokation());
3391
3392         return _Jv_JNI_GetStringChars(env, string, isCopy);
3393 }
3394
3395
3396 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3397                                                                    const jchar *cstring)
3398 {
3399         STATISTICS(jniinvokation());
3400
3401         _Jv_JNI_ReleaseStringChars(env, string, cstring);
3402 }
3403
3404
3405 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3406 {
3407         STATISTICS(jniinvokation());
3408
3409         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3410
3411         return obj;
3412 }
3413
3414
3415 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3416 {
3417         STATISTICS(jniinvokation());
3418
3419         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3420 }
3421
3422
3423 /* NewGlobalRef ****************************************************************
3424
3425    Creates a new global reference to the object referred to by the obj
3426    argument.
3427
3428 *******************************************************************************/
3429     
3430 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3431 {
3432         hashtable_global_ref_entry *gre;
3433         u4   key;                           /* hashkey                            */
3434         u4   slot;                          /* slot in hashtable                  */
3435         java_handle_t *o;
3436
3437         STATISTICS(jniinvokation());
3438
3439         o = (java_handle_t *) obj;
3440
3441         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3442
3443         /* normally addresses are aligned to 4, 8 or 16 bytes */
3444
3445         key  = ((u4) (ptrint) obj) >> 4;           /* align to 16-byte boundaries */
3446         slot = key & (hashtable_global_ref->size - 1);
3447         gre  = hashtable_global_ref->ptr[slot];
3448         
3449         /* search external hash chain for the entry */
3450
3451         while (gre) {
3452                 if (gre->o == o) {
3453                         /* global object found, increment the reference */
3454
3455                         gre->refs++;
3456
3457                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3458
3459                         return obj;
3460                 }
3461
3462                 gre = gre->hashlink;                /* next element in external chain */
3463         }
3464
3465         /* global ref not found, create a new one */
3466
3467         gre = NEW(hashtable_global_ref_entry);
3468
3469 #if defined(ENABLE_GC_CACAO)
3470         /* register global ref with the GC */
3471
3472         gc_reference_register(&(gre->o));
3473 #endif
3474
3475         gre->o    = o;
3476         gre->refs = 1;
3477
3478         /* insert entry into hashtable */
3479
3480         gre->hashlink = hashtable_global_ref->ptr[slot];
3481
3482         hashtable_global_ref->ptr[slot] = gre;
3483
3484         /* update number of hashtable-entries */
3485
3486         hashtable_global_ref->entries++;
3487
3488         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3489
3490         return obj;
3491 }
3492
3493
3494 /* DeleteGlobalRef *************************************************************
3495
3496    Deletes the global reference pointed to by globalRef.
3497
3498 *******************************************************************************/
3499
3500 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3501 {
3502         hashtable_global_ref_entry *gre;
3503         hashtable_global_ref_entry *prevgre;
3504         u4   key;                           /* hashkey                            */
3505         u4   slot;                          /* slot in hashtable                  */
3506         java_handle_t              *o;
3507
3508         STATISTICS(jniinvokation());
3509
3510         o = (java_handle_t *) globalRef;
3511
3512         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3513
3514         /* normally addresses are aligned to 4, 8 or 16 bytes */
3515
3516         key  = ((u4) (ptrint) globalRef) >> 4;     /* align to 16-byte boundaries */
3517         slot = key & (hashtable_global_ref->size - 1);
3518         gre  = hashtable_global_ref->ptr[slot];
3519
3520         /* initialize prevgre */
3521
3522         prevgre = NULL;
3523
3524         /* search external hash chain for the entry */
3525
3526         while (gre) {
3527                 if (gre->o == o) {
3528                         /* global object found, decrement the reference count */
3529
3530                         gre->refs--;
3531
3532                         /* if reference count is 0, remove the entry */
3533
3534                         if (gre->refs == 0) {
3535                                 /* special handling if it's the first in the chain */
3536
3537                                 if (prevgre == NULL)
3538                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
3539                                 else
3540                                         prevgre->hashlink = gre->hashlink;
3541
3542 #if defined(ENABLE_GC_CACAO)
3543                                 /* unregister global ref with the GC */
3544
3545                                 gc_reference_unregister(&(gre->o));
3546 #endif
3547
3548                                 FREE(gre, hashtable_global_ref_entry);
3549                         }
3550
3551                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3552
3553                         return;
3554                 }
3555
3556                 prevgre = gre;                    /* save current pointer for removal */
3557                 gre     = gre->hashlink;            /* next element in external chain */
3558         }
3559
3560         log_println("JNI-DeleteGlobalRef: global reference not found");
3561
3562         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3563 }
3564
3565
3566 /* ExceptionCheck **************************************************************
3567
3568    Returns JNI_TRUE when there is a pending exception; otherwise,
3569    returns JNI_FALSE.
3570
3571 *******************************************************************************/
3572
3573 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3574 {
3575         java_handle_t *o;
3576
3577         STATISTICS(jniinvokation());
3578
3579         o = exceptions_get_exception();
3580
3581         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3582 }
3583
3584
3585 /* New JNI 1.4 functions ******************************************************/
3586
3587 /* NewDirectByteBuffer *********************************************************
3588
3589    Allocates and returns a direct java.nio.ByteBuffer referring to the
3590    block of memory starting at the memory address address and
3591    extending capacity bytes.
3592
3593 *******************************************************************************/
3594
3595 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3596 {
3597 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3598         java_handle_t           *nbuf;
3599
3600 # if SIZEOF_VOID_P == 8
3601         gnu_classpath_Pointer64 *paddress;
3602 # else
3603         gnu_classpath_Pointer32 *paddress;
3604 # endif
3605
3606         STATISTICS(jniinvokation());
3607
3608         /* alocate a gnu.classpath.Pointer{32,64} object */
3609
3610 # if SIZEOF_VOID_P == 8
3611         if (!(paddress = (gnu_classpath_Pointer64 *)
3612                   builtin_new(class_gnu_classpath_Pointer64)))
3613 # else
3614         if (!(paddress = (gnu_classpath_Pointer32 *)
3615                   builtin_new(class_gnu_classpath_Pointer32)))
3616 # endif
3617                 return NULL;
3618
3619         /* fill gnu.classpath.Pointer{32,64} with address */
3620
3621         LLNI_field_set_val(paddress, data, (ptrint) address);
3622
3623         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3624
3625         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3626                                                          (jmethodID) dbbirw_init, NULL, paddress,
3627                                                          (jint) capacity, (jint) capacity, (jint) 0);
3628
3629         /* add local reference and return the value */
3630
3631         return _Jv_JNI_NewLocalRef(env, nbuf);
3632 #else
3633         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3634
3635         /* keep compiler happy */
3636
3637         return NULL;
3638 #endif
3639 }
3640
3641
3642 /* GetDirectBufferAddress ******************************************************
3643
3644    Fetches and returns the starting address of the memory region
3645    referenced by the given direct java.nio.Buffer.
3646
3647 *******************************************************************************/
3648
3649 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3650 {
3651 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3652         java_nio_DirectByteBufferImpl *nbuf;
3653 # if SIZEOF_VOID_P == 8
3654         gnu_classpath_Pointer64       *paddress;
3655 # else
3656         gnu_classpath_Pointer32       *paddress;
3657 # endif
3658         void                          *address;
3659
3660         STATISTICS(jniinvokation());
3661
3662         if (!builtin_instanceof(buf, class_java_nio_Buffer))
3663                 return NULL;
3664
3665         nbuf = (java_nio_DirectByteBufferImpl *) buf;
3666
3667 # if SIZEOF_VOID_P == 8
3668         LLNI_field_get_ref(nbuf, address, paddress);
3669         /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3670 # else
3671         LLNI_field_get_ref(nbuf, address, paddress); 
3672         /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3673 # endif
3674
3675         if (paddress == NULL)
3676                 return NULL;
3677
3678         LLNI_field_get_val(paddress, data, address);
3679         /* this was the cast to avaoid warning: (void *) paddress->data */
3680
3681         return address;
3682 #else
3683         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3684
3685         /* keep compiler happy */
3686
3687         return NULL;
3688 #endif
3689 }
3690
3691
3692 /* GetDirectBufferCapacity *****************************************************
3693
3694    Fetches and returns the capacity in bytes of the memory region
3695    referenced by the given direct java.nio.Buffer.
3696
3697 *******************************************************************************/
3698
3699 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3700 {
3701 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3702         java_handle_t   *o;
3703         java_nio_Buffer *nbuf;
3704         jlong            capacity;
3705
3706         STATISTICS(jniinvokation());
3707
3708         o = (java_handle_t *) buf;
3709
3710         if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3711                 return -1;
3712
3713         nbuf = (java_nio_Buffer *) o;
3714
3715         LLNI_field_get_val(nbuf, cap, capacity);
3716
3717         return capacity;
3718 #else
3719         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3720
3721         /* keep compiler happy */
3722
3723         return 0;
3724 #endif
3725 }
3726
3727
3728 /* DestroyJavaVM ***************************************************************
3729
3730    Unloads a Java VM and reclaims its resources. Only the main thread
3731    can unload the VM. The system waits until the main thread is only
3732    remaining user thread before it destroys the VM.
3733
3734 *******************************************************************************/
3735
3736 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3737 {
3738         s4 status;
3739
3740         STATISTICS(jniinvokation());
3741
3742     status = vm_destroy(vm);
3743
3744         return status;
3745 }
3746
3747
3748 /* AttachCurrentThread *********************************************************
3749
3750    Attaches the current thread to a Java VM. Returns a JNI interface
3751    pointer in the JNIEnv argument.
3752
3753    Trying to attach a thread that is already attached is a no-op.
3754
3755    A native thread cannot be attached simultaneously to two Java VMs.
3756
3757    When a thread is attached to the VM, the context class loader is
3758    the bootstrap loader.
3759
3760 *******************************************************************************/
3761
3762 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3763 {
3764         JavaVMAttachArgs *vm_aargs;
3765
3766 #if defined(ENABLE_THREADS)
3767         if (threads_get_current_threadobject() == NULL) {
3768                 vm_aargs = (JavaVMAttachArgs *) thr_args;
3769
3770                 if (vm_aargs != NULL) {
3771                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
3772                                 (vm_aargs->version != JNI_VERSION_1_4))
3773                                 return JNI_EVERSION;
3774                 }
3775
3776                 if (!threads_attach_current_thread(vm_aargs, false))
3777                         return JNI_ERR;
3778
3779                 if (!localref_table_init())
3780                         return JNI_ERR;
3781         }
3782 #endif
3783
3784         *p_env = _Jv_env;
3785
3786         return JNI_OK;
3787 }
3788
3789
3790 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3791 {
3792         STATISTICS(jniinvokation());
3793
3794         return jni_attach_current_thread(p_env, thr_args, false);
3795 }
3796
3797
3798 /* DetachCurrentThread *********************************************************
3799
3800    Detaches the current thread from a Java VM. All Java monitors held
3801    by this thread are released. All Java threads waiting for this
3802    thread to die are notified.
3803
3804    In JDK 1.1, the main thread cannot be detached from the VM. It must
3805    call DestroyJavaVM to unload the entire VM.
3806
3807    In the JDK, the main thread can be detached from the VM.
3808
3809    The main thread, which is the thread that created the Java VM,
3810    cannot be detached from the VM. Instead, the main thread must call
3811    JNI_DestroyJavaVM() to unload the entire VM.
3812
3813 *******************************************************************************/
3814
3815 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3816 {
3817 #if defined(ENABLE_THREADS)
3818         threadobject *thread;
3819
3820         STATISTICS(jniinvokation());
3821
3822         thread = threads_get_current_threadobject();
3823
3824         if (thread == NULL)
3825                 return JNI_ERR;
3826
3827         if (!jni_free_localref_table())
3828                 return JNI_ERR;
3829
3830         if (!threads_detach_thread(thread))
3831                 return JNI_ERR;
3832 #endif
3833
3834         return JNI_OK;
3835 }
3836
3837
3838 /* GetEnv **********************************************************************
3839
3840    If the current thread is not attached to the VM, sets *env to NULL,
3841    and returns JNI_EDETACHED. If the specified version is not
3842    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3843    sets *env to the appropriate interface, and returns JNI_OK.
3844
3845 *******************************************************************************/
3846
3847 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3848 {
3849         STATISTICS(jniinvokation());
3850
3851 #if defined(ENABLE_THREADS)
3852         if (threads_get_current_threadobject() == NULL) {
3853                 *env = NULL;
3854
3855                 return JNI_EDETACHED;
3856         }
3857 #endif
3858
3859         /* check the JNI version */
3860
3861         switch (version) {
3862         case JNI_VERSION_1_1:
3863         case JNI_VERSION_1_2:
3864         case JNI_VERSION_1_4:
3865                 *env = _Jv_env;
3866                 return JNI_OK;
3867
3868         default:
3869                 ;
3870         }
3871
3872 #if defined(ENABLE_JVMTI)
3873         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
3874                 == JVMTI_VERSION_INTERFACE_JVMTI) {
3875
3876                 *env = (void *) jvmti_new_environment();
3877
3878                 if (env != NULL)
3879                         return JNI_OK;
3880         }
3881 #endif
3882         
3883         *env = NULL;
3884
3885         return JNI_EVERSION;
3886 }
3887
3888
3889 /* AttachCurrentThreadAsDaemon *************************************************
3890
3891    Same semantics as AttachCurrentThread, but the newly-created
3892    java.lang.Thread instance is a daemon.
3893
3894    If the thread has already been attached via either
3895    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3896    simply sets the value pointed to by penv to the JNIEnv of the
3897    current thread. In this case neither AttachCurrentThread nor this
3898    routine have any effect on the daemon status of the thread.
3899
3900 *******************************************************************************/
3901
3902 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3903 {
3904         STATISTICS(jniinvokation());
3905
3906         return jni_attach_current_thread(penv, args, true);
3907 }
3908
3909
3910 /* JNI invocation table *******************************************************/
3911
3912 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3913         NULL,
3914         NULL,
3915         NULL,
3916
3917         _Jv_JNI_DestroyJavaVM,
3918         _Jv_JNI_AttachCurrentThread,
3919         _Jv_JNI_DetachCurrentThread,
3920         _Jv_JNI_GetEnv,
3921         _Jv_JNI_AttachCurrentThreadAsDaemon
3922 };
3923
3924
3925 /* JNI function table *********************************************************/
3926
3927 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3928         NULL,
3929         NULL,
3930         NULL,
3931         NULL,    
3932         _Jv_JNI_GetVersion,
3933
3934         _Jv_JNI_DefineClass,
3935         _Jv_JNI_FindClass,
3936         _Jv_JNI_FromReflectedMethod,
3937         _Jv_JNI_FromReflectedField,
3938         _Jv_JNI_ToReflectedMethod,
3939         _Jv_JNI_GetSuperclass,
3940         _Jv_JNI_IsAssignableFrom,
3941         _Jv_JNI_ToReflectedField,
3942
3943         _Jv_JNI_Throw,
3944         _Jv_JNI_ThrowNew,
3945         _Jv_JNI_ExceptionOccurred,
3946         _Jv_JNI_ExceptionDescribe,
3947         _Jv_JNI_ExceptionClear,
3948         _Jv_JNI_FatalError,
3949         _Jv_JNI_PushLocalFrame,
3950         _Jv_JNI_PopLocalFrame,
3951
3952         _Jv_JNI_NewGlobalRef,
3953         _Jv_JNI_DeleteGlobalRef,
3954         _Jv_JNI_DeleteLocalRef,
3955         _Jv_JNI_IsSameObject,
3956         _Jv_JNI_NewLocalRef,
3957         _Jv_JNI_EnsureLocalCapacity,
3958
3959         _Jv_JNI_AllocObject,
3960         _Jv_JNI_NewObject,
3961         _Jv_JNI_NewObjectV,
3962         _Jv_JNI_NewObjectA,
3963
3964         _Jv_JNI_GetObjectClass,
3965         _Jv_JNI_IsInstanceOf,
3966
3967         _Jv_JNI_GetMethodID,
3968
3969         _Jv_JNI_CallObjectMethod,
3970         _Jv_JNI_CallObjectMethodV,
3971         _Jv_JNI_CallObjectMethodA,
3972         _Jv_JNI_CallBooleanMethod,
3973         _Jv_JNI_CallBooleanMethodV,
3974         _Jv_JNI_CallBooleanMethodA,
3975         _Jv_JNI_CallByteMethod,
3976         _Jv_JNI_CallByteMethodV,
3977         _Jv_JNI_CallByteMethodA,
3978         _Jv_JNI_CallCharMethod,
3979         _Jv_JNI_CallCharMethodV,
3980         _Jv_JNI_CallCharMethodA,
3981         _Jv_JNI_CallShortMethod,
3982         _Jv_JNI_CallShortMethodV,
3983         _Jv_JNI_CallShortMethodA,
3984         _Jv_JNI_CallIntMethod,
3985         _Jv_JNI_CallIntMethodV,
3986         _Jv_JNI_CallIntMethodA,
3987         _Jv_JNI_CallLongMethod,
3988         _Jv_JNI_CallLongMethodV,
3989         _Jv_JNI_CallLongMethodA,
3990         _Jv_JNI_CallFloatMethod,
3991         _Jv_JNI_CallFloatMethodV,
3992         _Jv_JNI_CallFloatMethodA,
3993         _Jv_JNI_CallDoubleMethod,
3994         _Jv_JNI_CallDoubleMethodV,
3995         _Jv_JNI_CallDoubleMethodA,
3996         _Jv_JNI_CallVoidMethod,
3997         _Jv_JNI_CallVoidMethodV,
3998         _Jv_JNI_CallVoidMethodA,
3999
4000         _Jv_JNI_CallNonvirtualObjectMethod,
4001         _Jv_JNI_CallNonvirtualObjectMethodV,
4002         _Jv_JNI_CallNonvirtualObjectMethodA,
4003         _Jv_JNI_CallNonvirtualBooleanMethod,
4004         _Jv_JNI_CallNonvirtualBooleanMethodV,
4005         _Jv_JNI_CallNonvirtualBooleanMethodA,
4006         _Jv_JNI_CallNonvirtualByteMethod,
4007         _Jv_JNI_CallNonvirtualByteMethodV,
4008         _Jv_JNI_CallNonvirtualByteMethodA,
4009         _Jv_JNI_CallNonvirtualCharMethod,
4010         _Jv_JNI_CallNonvirtualCharMethodV,
4011         _Jv_JNI_CallNonvirtualCharMethodA,
4012         _Jv_JNI_CallNonvirtualShortMethod,
4013         _Jv_JNI_CallNonvirtualShortMethodV,
4014         _Jv_JNI_CallNonvirtualShortMethodA,
4015         _Jv_JNI_CallNonvirtualIntMethod,
4016         _Jv_JNI_CallNonvirtualIntMethodV,
4017         _Jv_JNI_CallNonvirtualIntMethodA,
4018         _Jv_JNI_CallNonvirtualLongMethod,
4019         _Jv_JNI_CallNonvirtualLongMethodV,
4020         _Jv_JNI_CallNonvirtualLongMethodA,
4021         _Jv_JNI_CallNonvirtualFloatMethod,
4022         _Jv_JNI_CallNonvirtualFloatMethodV,
4023         _Jv_JNI_CallNonvirtualFloatMethodA,
4024         _Jv_JNI_CallNonvirtualDoubleMethod,
4025         _Jv_JNI_CallNonvirtualDoubleMethodV,
4026         _Jv_JNI_CallNonvirtualDoubleMethodA,
4027         _Jv_JNI_CallNonvirtualVoidMethod,
4028         _Jv_JNI_CallNonvirtualVoidMethodV,
4029         _Jv_JNI_CallNonvirtualVoidMethodA,
4030
4031         _Jv_JNI_GetFieldID,
4032
4033         _Jv_JNI_GetObjectField,
4034         _Jv_JNI_GetBooleanField,
4035         _Jv_JNI_GetByteField,
4036         _Jv_JNI_GetCharField,
4037         _Jv_JNI_GetShortField,
4038         _Jv_JNI_GetIntField,
4039         _Jv_JNI_GetLongField,
4040         _Jv_JNI_GetFloatField,
4041         _Jv_JNI_GetDoubleField,
4042         _Jv_JNI_SetObjectField,
4043         _Jv_JNI_SetBooleanField,
4044         _Jv_JNI_SetByteField,
4045         _Jv_JNI_SetCharField,
4046         _Jv_JNI_SetShortField,
4047         _Jv_JNI_SetIntField,
4048         _Jv_JNI_SetLongField,
4049         _Jv_JNI_SetFloatField,
4050         _Jv_JNI_SetDoubleField,
4051
4052         _Jv_JNI_GetStaticMethodID,
4053
4054         _Jv_JNI_CallStaticObjectMethod,
4055         _Jv_JNI_CallStaticObjectMethodV,
4056         _Jv_JNI_CallStaticObjectMethodA,
4057         _Jv_JNI_CallStaticBooleanMethod,
4058         _Jv_JNI_CallStaticBooleanMethodV,
4059         _Jv_JNI_CallStaticBooleanMethodA,
4060         _Jv_JNI_CallStaticByteMethod,
4061         _Jv_JNI_CallStaticByteMethodV,
4062         _Jv_JNI_CallStaticByteMethodA,
4063         _Jv_JNI_CallStaticCharMethod,
4064         _Jv_JNI_CallStaticCharMethodV,
4065         _Jv_JNI_CallStaticCharMethodA,
4066         _Jv_JNI_CallStaticShortMethod,
4067         _Jv_JNI_CallStaticShortMethodV,
4068         _Jv_JNI_CallStaticShortMethodA,
4069         _Jv_JNI_CallStaticIntMethod,
4070         _Jv_JNI_CallStaticIntMethodV,
4071         _Jv_JNI_CallStaticIntMethodA,
4072         _Jv_JNI_CallStaticLongMethod,
4073         _Jv_JNI_CallStaticLongMethodV,
4074         _Jv_JNI_CallStaticLongMethodA,
4075         _Jv_JNI_CallStaticFloatMethod,
4076         _Jv_JNI_CallStaticFloatMethodV,
4077         _Jv_JNI_CallStaticFloatMethodA,
4078         _Jv_JNI_CallStaticDoubleMethod,
4079         _Jv_JNI_CallStaticDoubleMethodV,
4080         _Jv_JNI_CallStaticDoubleMethodA,
4081         _Jv_JNI_CallStaticVoidMethod,
4082         _Jv_JNI_CallStaticVoidMethodV,
4083         _Jv_JNI_CallStaticVoidMethodA,
4084
4085         _Jv_JNI_GetStaticFieldID,
4086
4087         _Jv_JNI_GetStaticObjectField,
4088         _Jv_JNI_GetStaticBooleanField,
4089         _Jv_JNI_GetStaticByteField,
4090         _Jv_JNI_GetStaticCharField,
4091         _Jv_JNI_GetStaticShortField,
4092         _Jv_JNI_GetStaticIntField,
4093         _Jv_JNI_GetStaticLongField,
4094         _Jv_JNI_GetStaticFloatField,
4095         _Jv_JNI_GetStaticDoubleField,
4096         _Jv_JNI_SetStaticObjectField,
4097         _Jv_JNI_SetStaticBooleanField,
4098         _Jv_JNI_SetStaticByteField,
4099         _Jv_JNI_SetStaticCharField,
4100         _Jv_JNI_SetStaticShortField,
4101         _Jv_JNI_SetStaticIntField,
4102         _Jv_JNI_SetStaticLongField,
4103         _Jv_JNI_SetStaticFloatField,
4104         _Jv_JNI_SetStaticDoubleField,
4105
4106         _Jv_JNI_NewString,
4107         _Jv_JNI_GetStringLength,
4108         _Jv_JNI_GetStringChars,
4109         _Jv_JNI_ReleaseStringChars,
4110
4111         _Jv_JNI_NewStringUTF,
4112         _Jv_JNI_GetStringUTFLength,
4113         _Jv_JNI_GetStringUTFChars,
4114         _Jv_JNI_ReleaseStringUTFChars,
4115
4116         _Jv_JNI_GetArrayLength,
4117
4118         _Jv_JNI_NewObjectArray,
4119         _Jv_JNI_GetObjectArrayElement,
4120         _Jv_JNI_SetObjectArrayElement,
4121
4122         _Jv_JNI_NewBooleanArray,
4123         _Jv_JNI_NewByteArray,
4124         _Jv_JNI_NewCharArray,
4125         _Jv_JNI_NewShortArray,
4126         _Jv_JNI_NewIntArray,
4127         _Jv_JNI_NewLongArray,
4128         _Jv_JNI_NewFloatArray,
4129         _Jv_JNI_NewDoubleArray,
4130
4131         _Jv_JNI_GetBooleanArrayElements,
4132         _Jv_JNI_GetByteArrayElements,
4133         _Jv_JNI_GetCharArrayElements,
4134         _Jv_JNI_GetShortArrayElements,
4135         _Jv_JNI_GetIntArrayElements,
4136         _Jv_JNI_GetLongArrayElements,
4137         _Jv_JNI_GetFloatArrayElements,
4138         _Jv_JNI_GetDoubleArrayElements,
4139
4140         _Jv_JNI_ReleaseBooleanArrayElements,
4141         _Jv_JNI_ReleaseByteArrayElements,
4142         _Jv_JNI_ReleaseCharArrayElements,
4143         _Jv_JNI_ReleaseShortArrayElements,
4144         _Jv_JNI_ReleaseIntArrayElements,
4145         _Jv_JNI_ReleaseLongArrayElements,
4146         _Jv_JNI_ReleaseFloatArrayElements,
4147         _Jv_JNI_ReleaseDoubleArrayElements,
4148
4149         _Jv_JNI_GetBooleanArrayRegion,
4150         _Jv_JNI_GetByteArrayRegion,
4151         _Jv_JNI_GetCharArrayRegion,
4152         _Jv_JNI_GetShortArrayRegion,
4153         _Jv_JNI_GetIntArrayRegion,
4154         _Jv_JNI_GetLongArrayRegion,
4155         _Jv_JNI_GetFloatArrayRegion,
4156         _Jv_JNI_GetDoubleArrayRegion,
4157         _Jv_JNI_SetBooleanArrayRegion,
4158         _Jv_JNI_SetByteArrayRegion,
4159         _Jv_JNI_SetCharArrayRegion,
4160         _Jv_JNI_SetShortArrayRegion,
4161         _Jv_JNI_SetIntArrayRegion,
4162         _Jv_JNI_SetLongArrayRegion,
4163         _Jv_JNI_SetFloatArrayRegion,
4164         _Jv_JNI_SetDoubleArrayRegion,
4165
4166         _Jv_JNI_RegisterNatives,
4167         _Jv_JNI_UnregisterNatives,
4168
4169         _Jv_JNI_MonitorEnter,
4170         _Jv_JNI_MonitorExit,
4171
4172         _Jv_JNI_GetJavaVM,
4173
4174         /* new JNI 1.2 functions */
4175
4176         _Jv_JNI_GetStringRegion,
4177         _Jv_JNI_GetStringUTFRegion,
4178
4179         _Jv_JNI_GetPrimitiveArrayCritical,
4180         _Jv_JNI_ReleasePrimitiveArrayCritical,
4181
4182         _Jv_JNI_GetStringCritical,
4183         _Jv_JNI_ReleaseStringCritical,
4184
4185         _Jv_JNI_NewWeakGlobalRef,
4186         _Jv_JNI_DeleteWeakGlobalRef,
4187
4188         _Jv_JNI_ExceptionCheck,
4189
4190         /* new JNI 1.4 functions */
4191
4192         _Jv_JNI_NewDirectByteBuffer,
4193         _Jv_JNI_GetDirectBufferAddress,
4194         _Jv_JNI_GetDirectBufferCapacity
4195 };
4196
4197
4198 /* Invocation API Functions ***************************************************/
4199
4200 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4201
4202    Returns a default configuration for the Java VM.
4203
4204 *******************************************************************************/
4205
4206 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4207 {
4208         JavaVMInitArgs *_vm_args;
4209
4210         _vm_args = (JavaVMInitArgs *) vm_args;
4211
4212         /* GNU classpath currently supports JNI 1.2 */
4213
4214         switch (_vm_args->version) {
4215     case JNI_VERSION_1_1:
4216                 _vm_args->version = JNI_VERSION_1_1;
4217                 break;
4218
4219     case JNI_VERSION_1_2:
4220     case JNI_VERSION_1_4:
4221                 _vm_args->ignoreUnrecognized = JNI_FALSE;
4222                 _vm_args->options = NULL;
4223                 _vm_args->nOptions = 0;
4224                 break;
4225
4226     default:
4227                 return -1;
4228         }
4229   
4230         return 0;
4231 }
4232
4233
4234 /* JNI_GetCreatedJavaVMs *******************************************************
4235
4236    Returns all Java VMs that have been created. Pointers to VMs are written in
4237    the buffer vmBuf in the order they are created. At most bufLen number of
4238    entries will be written. The total number of created VMs is returned in
4239    *nVMs.
4240
4241 *******************************************************************************/
4242
4243 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4244 {
4245         TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4246
4247         if (bufLen <= 0)
4248                 return JNI_ERR;
4249
4250         /* We currently only support 1 VM running. */
4251
4252         vmBuf[0] = (JavaVM *) _Jv_jvm;
4253         *nVMs    = 1;
4254
4255     return JNI_OK;
4256 }
4257
4258
4259 /* JNI_CreateJavaVM ************************************************************
4260
4261    Loads and initializes a Java VM. The current thread becomes the main thread.
4262    Sets the env argument to the JNI interface pointer of the main thread.
4263
4264 *******************************************************************************/
4265
4266 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4267 {
4268         TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4269
4270         /* actually create the JVM */
4271
4272         if (!vm_createjvm(p_vm, p_env, vm_args))
4273                 return JNI_ERR;
4274
4275         return JNI_OK;
4276 }
4277
4278
4279 /*
4280  * These are local overrides for various environment variables in Emacs.
4281  * Please do not remove this and leave it at the end of the file, where
4282  * Emacs will automagically detect them.
4283  * ---------------------------------------------------------------------
4284  * Local variables:
4285  * mode: c
4286  * indent-tabs-mode: t
4287  * c-basic-offset: 4
4288  * tab-width: 4
4289  * End:
4290  * vim:noexpandtab:sw=4:ts=4:
4291  */