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