Merged revisions 8137-8178 via svnmerge from
[cacao.git] / src / native / jni.c
1 /* src/native/jni.c - implementation of the Java Native Interface functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: jni.c 8179 2007-07-05 11:21:08Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdint.h>
34 #include <string.h>
35
36 #include "vm/types.h"
37
38 #include "mm/gc-common.h"
39 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/native.h"
42
43 #if defined(ENABLE_JAVASE)
44 # if defined(WITH_CLASSPATH_GNU)
45 #  include "native/include/gnu_classpath_Pointer.h"
46
47 #  if SIZEOF_VOID_P == 8
48 #   include "native/include/gnu_classpath_Pointer64.h"
49 #  else
50 #   include "native/include/gnu_classpath_Pointer32.h"
51 #  endif
52 # endif
53 #endif
54
55 #include "native/include/java_lang_Object.h"
56 #include "native/include/java_lang_Byte.h"
57 #include "native/include/java_lang_Character.h"
58 #include "native/include/java_lang_Short.h"
59 #include "native/include/java_lang_Integer.h"
60 #include "native/include/java_lang_Boolean.h"
61 #include "native/include/java_lang_Long.h"
62 #include "native/include/java_lang_Float.h"
63 #include "native/include/java_lang_Double.h"
64 #include "native/include/java_lang_String.h"
65 #include "native/include/java_lang_Throwable.h"
66
67 #if defined(ENABLE_JAVASE)
68 # if defined(WITH_CLASSPATH_SUN)
69 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
70 # endif
71
72 # include "native/include/java_lang_ClassLoader.h"
73
74 # include "native/include/java_lang_reflect_Constructor.h"
75 # include "native/include/java_lang_reflect_Field.h"
76 # include "native/include/java_lang_reflect_Method.h"
77
78 # include "native/include/java_nio_Buffer.h"
79
80 # if defined(WITH_CLASSPATH_GNU)
81 #  include "native/include/java_nio_DirectByteBufferImpl.h"
82 # endif
83 #endif
84
85 #if defined(ENABLE_JVMTI)
86 # include "native/jvmti/cacaodbg.h"
87 #endif
88
89 #include "native/vm/java_lang_Class.h"
90
91 #if defined(ENABLE_JAVASE)
92 # include "native/vm/java_lang_ClassLoader.h"
93 # include "native/vm/reflect.h"
94 #endif
95
96 #include "threads/lock-common.h"
97 #include "threads/threads-common.h"
98
99 #include "toolbox/logging.h"
100
101 #include "vm/builtin.h"
102 #include "vm/exceptions.h"
103 #include "vm/global.h"
104 #include "vm/initialize.h"
105 #include "vm/resolve.h"
106 #include "vm/stringlocal.h"
107 #include "vm/vm.h"
108
109 #include "vm/jit/asmpart.h"
110 #include "vm/jit/jit.h"
111 #include "vm/jit/stacktrace.h"
112
113 #include "vmcore/loader.h"
114 #include "vmcore/options.h"
115 #include "vmcore/primitive.h"
116 #include "vmcore/statistics.h"
117
118
119 /* global variables ***********************************************************/
120
121 /* global reference table *****************************************************/
122
123 /* hashsize must be power of 2 */
124
125 #define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
126
127 static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
128
129
130 /* direct buffer stuff ********************************************************/
131
132 #if defined(ENABLE_JAVASE)
133 static classinfo *class_java_nio_Buffer;
134 static classinfo *class_java_nio_DirectByteBufferImpl;
135 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
136
137 # if defined(WITH_CLASSPATH_GNU)
138 #  if SIZEOF_VOID_P == 8
139 static classinfo *class_gnu_classpath_Pointer64;
140 #  else
141 static classinfo *class_gnu_classpath_Pointer32;
142 #  endif
143 # endif
144
145 static methodinfo *dbbirw_init;
146 #endif
147
148
149 /* local reference table ******************************************************/
150
151 #if !defined(ENABLE_THREADS)
152 localref_table *_no_threads_localref_table;
153 #endif
154
155
156 /* accessing instance fields macros *******************************************/
157
158 #define SET_FIELD(o,type,f,value) \
159     *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
160
161 #define GET_FIELD(o,type,f) \
162     *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
163
164
165 /* some forward declarations **************************************************/
166
167 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
168 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
169
170
171 /* jni_init ********************************************************************
172
173    Initialize the JNI subsystem.
174
175 *******************************************************************************/
176
177 bool jni_init(void)
178 {
179         /* create global ref hashtable */
180
181         hashtable_global_ref = NEW(hashtable);
182
183         hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
184
185
186 #if defined(ENABLE_JAVASE)
187         /* direct buffer stuff */
188
189         if (!(class_java_nio_Buffer =
190                   load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
191                 !link_class(class_java_nio_Buffer))
192                 return false;
193
194 # if defined(WITH_CLASSPATH_GNU)
195         if (!(class_java_nio_DirectByteBufferImpl =
196                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
197                 !link_class(class_java_nio_DirectByteBufferImpl))
198                 return false;
199
200         if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
201                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
202                 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
203                 return false;
204
205         if (!(dbbirw_init =
206                 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
207                                                         utf_init,
208                                                         utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
209                 return false;
210
211 #  if SIZEOF_VOID_P == 8
212         if (!(class_gnu_classpath_Pointer64 =
213                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
214                 !link_class(class_gnu_classpath_Pointer64))
215                 return false;
216 #  else
217         if (!(class_gnu_classpath_Pointer32 =
218                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
219                 !link_class(class_gnu_classpath_Pointer32))
220                 return false;
221 #  endif
222 # endif
223 #endif /* defined(ENABLE_JAVASE) */
224
225         return true;
226 }
227
228
229 /* jni_init_localref_table *****************************************************
230
231    Initializes the local references table of the current thread.
232
233 *******************************************************************************/
234
235 bool jni_init_localref_table(void)
236 {
237         localref_table *lrt;
238
239 #if defined(ENABLE_GC_CACAO)
240         /* XXX this one will never get freed for the main thread;
241            call jni_free_localref_table() if you want to do it! */
242         lrt = NEW(localref_table);
243 #else
244         lrt = GCNEW(localref_table);
245 #endif
246
247         if (lrt == NULL)
248                 return false;
249
250         lrt->capacity    = LOCALREFTABLE_CAPACITY;
251         lrt->used        = 0;
252         lrt->localframes = 1;
253         lrt->prev        = LOCALREFTABLE;
254
255         /* clear the references array (memset is faster then a for-loop) */
256
257         MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
258
259         LOCALREFTABLE = lrt;
260
261         return true;
262 }
263
264
265 /* jni_init_localref_table *****************************************************
266
267    Frees the local references table of the current thread.
268
269 *******************************************************************************/
270
271 bool jni_free_localref_table(void)
272 {
273         localref_table *lrt;
274
275 #if defined(ENABLE_GC_CACAO)
276         lrt = LOCALREFTABLE;
277
278         assert(lrt);
279         assert(lrt->prev == NULL);
280
281         FREE(lrt, localref_table);
282
283         LOCALREFTABLE = NULL;
284 #endif
285
286         return true;
287 }
288
289
290 /* _Jv_jni_CallObjectMethod ****************************************************
291
292    Internal function to call Java Object methods.
293
294 *******************************************************************************/
295
296 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
297                                                                                                    vftbl_t *vftbl,
298                                                                                                    methodinfo *m, va_list ap)
299 {
300         methodinfo        *resm;
301         java_objectheader *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_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
344                                                                                                         vftbl_t *vftbl,
345                                                                                                         methodinfo *m,
346                                                                                                         const jvalue *args)
347 {
348         methodinfo        *resm;
349         java_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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_objectheader *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 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__) \
817  && !defined(__M68K__) && !defined(__ARM__) && !defined(__SPARC_64__)
818 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
819                                                                                 java_objectarray *params)
820 {
821         methodinfo        *resm;
822         vm_arg            *vmargs;
823         java_objectheader *ro;
824         s4                 argcount;
825         s4                 paramcount;
826         java_objectheader *xptr;
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 && (params->header.size != 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(o->vftbl, m);
874         }
875         else {
876                 /* for static methods, just for convenience */
877                 resm = m;
878         }
879
880         vmargs = MNEW(vm_arg, argcount);
881
882         if (!vm_vmargs_from_objectarray(resm, o, vmargs, params)) {
883                 MFREE(vmargs, vm_arg, argcount);
884                 return NULL;
885         }
886
887         switch (resm->parseddesc->returntype.decltype) {
888         case TYPE_VOID:
889                 (void) vm_call_method_vmarg(resm, argcount, vmargs);
890
891                 ro = NULL;
892                 break;
893
894         case PRIMITIVETYPE_BOOLEAN: {
895                 s4 i;
896                 java_lang_Boolean *bo;
897
898                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
899
900                 ro = builtin_new(class_java_lang_Boolean);
901
902                 /* setting the value of the object direct */
903
904                 bo = (java_lang_Boolean *) ro;
905                 bo->value = i;
906         }
907         break;
908
909         case PRIMITIVETYPE_BYTE: {
910                 s4 i;
911                 java_lang_Byte *bo;
912
913                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
914
915                 ro = builtin_new(class_java_lang_Byte);
916
917                 /* setting the value of the object direct */
918
919                 bo = (java_lang_Byte *) ro;
920                 bo->value = i;
921         }
922         break;
923
924         case PRIMITIVETYPE_CHAR: {
925                 s4 i;
926                 java_lang_Character *co;
927
928                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
929
930                 ro = builtin_new(class_java_lang_Character);
931
932                 /* setting the value of the object direct */
933
934                 co = (java_lang_Character *) ro;
935                 co->value = i;
936         }
937         break;
938
939         case PRIMITIVETYPE_SHORT: {
940                 s4 i;
941                 java_lang_Short *so;
942
943                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
944
945                 ro = builtin_new(class_java_lang_Short);
946
947                 /* setting the value of the object direct */
948
949                 so = (java_lang_Short *) ro;
950                 so->value = i;
951         }
952         break;
953
954         case PRIMITIVETYPE_INT: {
955                 s4 i;
956                 java_lang_Integer *io;
957
958                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
959
960                 ro = builtin_new(class_java_lang_Integer);
961
962                 /* setting the value of the object direct */
963
964                 io = (java_lang_Integer *) ro;
965                 io->value = i;
966         }
967         break;
968
969         case PRIMITIVETYPE_LONG: {
970                 s8 l;
971                 java_lang_Long *lo;
972
973                 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
974
975                 ro = builtin_new(class_java_lang_Long);
976
977                 /* setting the value of the object direct */
978
979                 lo = (java_lang_Long *) ro;
980                 lo->value = l;
981         }
982         break;
983
984         case PRIMITIVETYPE_FLOAT: {
985                 float f;
986                 java_lang_Float *fo;
987
988                 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
989
990                 ro = builtin_new(class_java_lang_Float);
991
992                 /* setting the value of the object direct */
993
994                 fo = (java_lang_Float *) ro;
995                 fo->value = f;
996         }
997         break;
998
999         case PRIMITIVETYPE_DOUBLE: {
1000                 double d;
1001                 java_lang_Double *_do;
1002
1003                 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
1004
1005                 ro = builtin_new(class_java_lang_Double);
1006
1007                 /* setting the value of the object direct */
1008
1009                 _do = (java_lang_Double *) ro;
1010                 _do->value = d;
1011         }
1012         break;
1013
1014         case TYPE_ADR:
1015                 ro = vm_call_method_vmarg(resm, argcount, vmargs);
1016                 break;
1017
1018         default:
1019                 /* if this happens the exception has already been set by
1020                    fill_callblock_from_objectarray */
1021
1022                 MFREE(vmargs, vm_arg, argcount);
1023
1024                 return NULL;
1025         }
1026
1027         MFREE(vmargs, vm_arg, argcount);
1028
1029         xptr = exceptions_get_exception();
1030
1031         if (xptr != NULL) {
1032                 /* clear exception pointer, we are calling JIT code again */
1033
1034                 exceptions_clear_exception();
1035
1036                 exceptions_throw_invocationtargetexception(xptr);
1037         }
1038
1039         return ro;
1040 }
1041 #else
1042 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
1043                                                                                 java_objectarray *params)
1044 {
1045         methodinfo        *resm;
1046         java_objectheader *ro;
1047         s4                 argcount;
1048         s4                 paramcount;
1049         java_objectheader *xptr;
1050         int32_t            dumpsize;
1051         uint64_t          *array;
1052
1053         if (m == NULL) {
1054                 exceptions_throw_nullpointerexception();
1055                 return NULL;
1056         }
1057
1058         argcount = m->parseddesc->paramcount;
1059         paramcount = argcount;
1060
1061         /* if method is non-static, remove the `this' pointer */
1062
1063         if (!(m->flags & ACC_STATIC))
1064                 paramcount--;
1065
1066         /* For instance methods the object has to be an instance of the
1067            class the method belongs to. For static methods the obj
1068            parameter is ignored. */
1069
1070         if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
1071                 exceptions_throw_illegalargumentexception();
1072                 return NULL;
1073         }
1074
1075         /* check if we got the right number of arguments */
1076
1077         if (((params == NULL) && (paramcount != 0)) ||
1078                 (params && (params->header.size != paramcount))) 
1079         {
1080                 exceptions_throw_illegalargumentexception();
1081                 return NULL;
1082         }
1083
1084         /* for instance methods we need an object */
1085
1086         if (!(m->flags & ACC_STATIC) && (o == NULL)) {
1087                 /* XXX not sure if that is the correct exception */
1088                 exceptions_throw_nullpointerexception();
1089                 return NULL;
1090         }
1091
1092         /* for static methods, zero object to make subsequent code simpler */
1093         if (m->flags & ACC_STATIC)
1094                 o = NULL;
1095
1096         if (o != NULL) {
1097                 /* for instance methods we must do a vftbl lookup */
1098                 resm = method_vftbl_lookup(o->vftbl, m);
1099         }
1100         else {
1101                 /* for static methods, just for convenience */
1102                 resm = m;
1103         }
1104
1105         /* mark start of dump memory area */
1106
1107         dumpsize = dump_size();
1108
1109         /* fill the argument array from a object-array */
1110
1111         array = vm_array_from_objectarray(resm, o, params);
1112
1113         if (array == NULL) {
1114                 /* release dump area */
1115
1116                 dump_release(dumpsize);
1117
1118                 return NULL;
1119         }
1120
1121         switch (resm->parseddesc->returntype.decltype) {
1122         case TYPE_VOID:
1123                 (void) vm_call_array(resm, array);
1124
1125                 ro = NULL;
1126                 break;
1127
1128         case PRIMITIVETYPE_BOOLEAN: {
1129                 s4 i;
1130                 java_lang_Boolean *bo;
1131
1132                 i = vm_call_int_array(resm, array);
1133
1134                 ro = builtin_new(class_java_lang_Boolean);
1135
1136                 /* setting the value of the object direct */
1137
1138                 bo = (java_lang_Boolean *) ro;
1139                 bo->value = i;
1140         }
1141         break;
1142
1143         case PRIMITIVETYPE_BYTE: {
1144                 s4 i;
1145                 java_lang_Byte *bo;
1146
1147                 i = vm_call_int_array(resm, array);
1148
1149                 ro = builtin_new(class_java_lang_Byte);
1150
1151                 /* setting the value of the object direct */
1152
1153                 bo = (java_lang_Byte *) ro;
1154                 bo->value = i;
1155         }
1156         break;
1157
1158         case PRIMITIVETYPE_CHAR: {
1159                 s4 i;
1160                 java_lang_Character *co;
1161
1162                 i = vm_call_int_array(resm, array);
1163
1164                 ro = builtin_new(class_java_lang_Character);
1165
1166                 /* setting the value of the object direct */
1167
1168                 co = (java_lang_Character *) ro;
1169                 co->value = i;
1170         }
1171         break;
1172
1173         case PRIMITIVETYPE_SHORT: {
1174                 s4 i;
1175                 java_lang_Short *so;
1176
1177                 i = vm_call_int_array(resm, array);
1178
1179                 ro = builtin_new(class_java_lang_Short);
1180
1181                 /* setting the value of the object direct */
1182
1183                 so = (java_lang_Short *) ro;
1184                 so->value = i;
1185         }
1186         break;
1187
1188         case PRIMITIVETYPE_INT: {
1189                 s4 i;
1190                 java_lang_Integer *io;
1191
1192                 i = vm_call_int_array(resm, array);
1193
1194                 ro = builtin_new(class_java_lang_Integer);
1195
1196                 /* setting the value of the object direct */
1197
1198                 io = (java_lang_Integer *) ro;
1199                 io->value = i;
1200         }
1201         break;
1202
1203         case PRIMITIVETYPE_LONG: {
1204                 s8 l;
1205                 java_lang_Long *lo;
1206
1207                 l = vm_call_long_array(resm, array);
1208
1209                 ro = builtin_new(class_java_lang_Long);
1210
1211                 /* setting the value of the object direct */
1212
1213                 lo = (java_lang_Long *) ro;
1214                 lo->value = l;
1215         }
1216         break;
1217
1218         case PRIMITIVETYPE_FLOAT: {
1219                 float f;
1220                 java_lang_Float *fo;
1221
1222                 f = vm_call_float_array(resm, array);
1223
1224                 ro = builtin_new(class_java_lang_Float);
1225
1226                 /* setting the value of the object direct */
1227
1228                 fo = (java_lang_Float *) ro;
1229                 fo->value = f;
1230         }
1231         break;
1232
1233         case PRIMITIVETYPE_DOUBLE: {
1234                 double d;
1235                 java_lang_Double *_do;
1236
1237                 d = vm_call_double_array(resm, array);
1238
1239                 ro = builtin_new(class_java_lang_Double);
1240
1241                 /* setting the value of the object direct */
1242
1243                 _do = (java_lang_Double *) ro;
1244                 _do->value = d;
1245         }
1246         break;
1247
1248         case TYPE_ADR:
1249                 ro = vm_call_array(resm, array);
1250                 break;
1251
1252         default:
1253                 /* if this happens the exception has already been set by
1254                    fill_callblock_from_objectarray */
1255
1256                 /* release dump area */
1257
1258                 dump_release(dumpsize);
1259
1260                 return NULL;
1261         }
1262
1263         xptr = exceptions_get_exception();
1264
1265         if (xptr != NULL) {
1266                 /* clear exception pointer, we are calling JIT code again */
1267
1268                 exceptions_clear_exception();
1269
1270                 exceptions_throw_invocationtargetexception(xptr);
1271         }
1272
1273         /* release dump area */
1274
1275         dump_release(dumpsize);
1276
1277         return ro;
1278 }
1279 #endif
1280
1281
1282 /* GetVersion ******************************************************************
1283
1284    Returns the major version number in the higher 16 bits and the
1285    minor version number in the lower 16 bits.
1286
1287 *******************************************************************************/
1288
1289 jint _Jv_JNI_GetVersion(JNIEnv *env)
1290 {
1291         STATISTICS(jniinvokation());
1292
1293         /* we support JNI 1.4 */
1294
1295         return JNI_VERSION_1_4;
1296 }
1297
1298
1299 /* Class Operations ***********************************************************/
1300
1301 /* DefineClass *****************************************************************
1302
1303    Loads a class from a buffer of raw class data. The buffer
1304    containing the raw class data is not referenced by the VM after the
1305    DefineClass call returns, and it may be discarded if desired.
1306
1307 *******************************************************************************/
1308
1309 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
1310                                                    const jbyte *buf, jsize bufLen)
1311 {
1312 #if defined(ENABLE_JAVASE)
1313         java_lang_ClassLoader *cl;
1314         java_lang_String      *s;
1315         java_bytearray        *ba;
1316         jclass                 c;
1317
1318         STATISTICS(jniinvokation());
1319
1320         cl = (java_lang_ClassLoader *) loader;
1321         s  = (java_lang_String *) javastring_new_from_utf_string(name);
1322         ba = (java_bytearray *) buf;
1323
1324         c = (jclass) _Jv_java_lang_ClassLoader_defineClass(cl, s, ba, 0, bufLen,
1325                                                                                                            NULL);
1326
1327         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1328 #else
1329         vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
1330
1331         /* keep compiler happy */
1332
1333         return 0;
1334 #endif
1335 }
1336
1337
1338 /* FindClass *******************************************************************
1339
1340    This function loads a locally-defined class. It searches the
1341    directories and zip files specified by the CLASSPATH environment
1342    variable for the class with the specified name.
1343
1344 *******************************************************************************/
1345
1346 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
1347 {
1348 #if defined(ENABLE_JAVASE)
1349         utf       *u;
1350         classinfo *cc;
1351         classinfo *c;
1352
1353         STATISTICS(jniinvokation());
1354
1355         u = utf_new_char_classname((char *) name);
1356
1357         /* Check stacktrace for classloader, if one found use it,
1358            otherwise use the system classloader. */
1359
1360         /* Quote from the JNI documentation:
1361          
1362            In the Java 2 Platform, FindClass locates the class loader
1363            associated with the current native method.  If the native code
1364            belongs to a system class, no class loader will be
1365            involved. Otherwise, the proper class loader will be invoked to
1366            load and link the named class. When FindClass is called through
1367            the Invocation Interface, there is no current native method or
1368            its associated class loader. In that case, the result of
1369            ClassLoader.getBaseClassLoader is used." */
1370
1371         cc = stacktrace_getCurrentClass();
1372
1373         if (cc == NULL)
1374                 c = load_class_from_sysloader(u);
1375         else
1376                 c = load_class_from_classloader(u, cc->classloader);
1377
1378         if (c == NULL)
1379                 return NULL;
1380
1381         if (!link_class(c))
1382                 return NULL;
1383
1384         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1385 #else
1386         vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1387
1388         /* keep compiler happy */
1389
1390         return NULL;
1391 #endif
1392 }
1393   
1394
1395 /* GetSuperclass ***************************************************************
1396
1397    If clazz represents any class other than the class Object, then
1398    this function returns the object that represents the superclass of
1399    the class specified by clazz.
1400
1401 *******************************************************************************/
1402  
1403 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1404 {
1405         classinfo *c;
1406
1407         STATISTICS(jniinvokation());
1408
1409         c = ((classinfo *) sub)->super.cls;
1410
1411         if (!c)
1412                 return NULL;
1413
1414         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1415 }
1416   
1417  
1418 /* IsAssignableFrom ************************************************************
1419
1420    Determines whether an object of sub can be safely cast to sup.
1421
1422 *******************************************************************************/
1423
1424 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1425 {
1426         java_lang_Class *csup;
1427         java_lang_Class *csub;
1428
1429         csup = (java_lang_Class *) sup;
1430         csub = (java_lang_Class *) sub;
1431
1432         STATISTICS(jniinvokation());
1433
1434         return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1435 }
1436
1437
1438 /* Throw ***********************************************************************
1439
1440    Causes a java.lang.Throwable object to be thrown.
1441
1442 *******************************************************************************/
1443
1444 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1445 {
1446         java_objectheader *o;
1447
1448         STATISTICS(jniinvokation());
1449
1450         o = (java_objectheader *) obj;
1451
1452         exceptions_set_exception(o);
1453
1454         return JNI_OK;
1455 }
1456
1457
1458 /* ThrowNew ********************************************************************
1459
1460    Constructs an exception object from the specified class with the
1461    message specified by message and causes that exception to be
1462    thrown.
1463
1464 *******************************************************************************/
1465
1466 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1467 {
1468         classinfo         *c;
1469         java_objectheader *o;
1470         java_objectheader *s;
1471
1472         STATISTICS(jniinvokation());
1473
1474         c = (classinfo *) clazz;
1475         if (msg == NULL)
1476                 msg = "";
1477         s = javastring_new_from_utf_string(msg);
1478
1479         /* instantiate exception object */
1480
1481         o = native_new_and_init_string(c, s);
1482
1483         if (o == NULL)
1484                 return -1;
1485
1486         exceptions_set_exception(o);
1487
1488         return 0;
1489 }
1490
1491
1492 /* ExceptionOccurred ***********************************************************
1493
1494    Determines if an exception is being thrown. The exception stays
1495    being thrown until either the native code calls ExceptionClear(),
1496    or the Java code handles the exception.
1497
1498 *******************************************************************************/
1499
1500 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1501 {
1502         java_objectheader *o;
1503
1504         STATISTICS(jniinvokation());
1505
1506         o = exceptions_get_exception();
1507
1508         return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1509 }
1510
1511
1512 /* ExceptionDescribe ***********************************************************
1513
1514    Prints an exception and a backtrace of the stack to a system
1515    error-reporting channel, such as stderr. This is a convenience
1516    routine provided for debugging.
1517
1518 *******************************************************************************/
1519
1520 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1521 {
1522         java_objectheader *o;
1523         methodinfo        *m;
1524
1525         STATISTICS(jniinvokation());
1526
1527         o = exceptions_get_exception();
1528
1529         if (o == NULL) {
1530                 /* clear exception, because we are calling jit code again */
1531
1532                 exceptions_clear_exception();
1533
1534                 /* get printStackTrace method from exception class */
1535
1536                 m = class_resolveclassmethod(o->vftbl->class,
1537                                                                          utf_printStackTrace,
1538                                                                          utf_void__void,
1539                                                                          NULL,
1540                                                                          true);
1541
1542                 if (m == NULL)
1543                         /* XXX what should we do? */
1544                         return;
1545
1546                 /* print the stacktrace */
1547
1548                 (void) vm_call_method(m, o);
1549         }
1550 }
1551
1552
1553 /* ExceptionClear **************************************************************
1554
1555    Clears any exception that is currently being thrown. If no
1556    exception is currently being thrown, this routine has no effect.
1557
1558 *******************************************************************************/
1559
1560 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1561 {
1562         STATISTICS(jniinvokation());
1563
1564         exceptions_clear_exception();
1565 }
1566
1567
1568 /* FatalError ******************************************************************
1569
1570    Raises a fatal error and does not expect the VM to recover. This
1571    function does not return.
1572
1573 *******************************************************************************/
1574
1575 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1576 {
1577         STATISTICS(jniinvokation());
1578
1579         /* this seems to be the best way */
1580
1581         vm_abort("JNI Fatal error: %s", msg);
1582 }
1583
1584
1585 /* PushLocalFrame **************************************************************
1586
1587    Creates a new local reference frame, in which at least a given
1588    number of local references can be created.
1589
1590 *******************************************************************************/
1591
1592 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1593 {
1594         s4              additionalrefs;
1595         localref_table *lrt;
1596         localref_table *nlrt;
1597
1598         STATISTICS(jniinvokation());
1599
1600         if (capacity <= 0)
1601                 return -1;
1602
1603         /* Allocate new local reference table on Java heap.  Calculate the
1604            additional memory we have to allocate. */
1605
1606         if (capacity > LOCALREFTABLE_CAPACITY)
1607                 additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
1608         else
1609                 additionalrefs = 0;
1610
1611 #if defined(ENABLE_GC_CACAO)
1612         nlrt = MNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
1613 #else
1614         nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
1615 #endif
1616
1617         if (nlrt == NULL)
1618                 return -1;
1619
1620         /* get current local reference table from thread */
1621
1622         lrt = LOCALREFTABLE;
1623
1624         /* Set up the new local reference table and add it to the local
1625            frames chain. */
1626
1627         nlrt->capacity    = capacity;
1628         nlrt->used        = 0;
1629         nlrt->localframes = lrt->localframes + 1;
1630         nlrt->prev        = lrt;
1631
1632         /* store new local reference table in thread */
1633
1634         LOCALREFTABLE = nlrt;
1635
1636         return 0;
1637 }
1638
1639
1640 /* PopLocalFrame ***************************************************************
1641
1642    Pops off the current local reference frame, frees all the local
1643    references, and returns a local reference in the previous local
1644    reference frame for the given result object.
1645
1646 *******************************************************************************/
1647
1648 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1649 {
1650         localref_table *lrt;
1651         localref_table *plrt;
1652         s4              localframes;
1653         s4              additionalrefs;
1654
1655         STATISTICS(jniinvokation());
1656
1657         /* get current local reference table from thread */
1658
1659         lrt = LOCALREFTABLE;
1660
1661         localframes = lrt->localframes;
1662
1663         /* Don't delete the top local frame, as this one is allocated in
1664            the native stub on the stack and is freed automagically on
1665            return. */
1666
1667         if (localframes == 1)
1668                 return _Jv_JNI_NewLocalRef(env, result);
1669
1670         /* release all current local frames */
1671
1672         for (; localframes >= 1; localframes--) {
1673                 /* get previous frame */
1674
1675                 plrt = lrt->prev;
1676
1677                 /* clear all reference entries */
1678
1679                 MSET(&lrt->refs[0], 0, java_objectheader*, lrt->capacity);
1680
1681                 lrt->prev = NULL;
1682
1683 #if defined(ENABLE_GC_CACAO)
1684                 /* for the exact GC local reference tables are not on the heap,
1685                    so we need to free them explicitly here. */
1686
1687                 if (lrt->capacity > LOCALREFTABLE_CAPACITY)
1688                         additionalrefs = lrt->capacity - LOCALREFTABLE_CAPACITY;
1689                 else
1690                         additionalrefs = 0;
1691
1692                 MFREE(lrt, u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
1693 #endif
1694
1695                 /* set new local references table */
1696
1697                 lrt = plrt;
1698         }
1699
1700         /* store new local reference table in thread */
1701
1702         LOCALREFTABLE = lrt;
1703
1704         /* add local reference and return the value */
1705
1706         return _Jv_JNI_NewLocalRef(env, result);
1707 }
1708
1709
1710 /* DeleteLocalRef **************************************************************
1711
1712    Deletes the local reference pointed to by localRef.
1713
1714 *******************************************************************************/
1715
1716 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1717 {
1718         java_objectheader *o;
1719         localref_table    *lrt;
1720         s4                 i;
1721
1722         STATISTICS(jniinvokation());
1723
1724         o = (java_objectheader *) localRef;
1725
1726         /* get local reference table (thread specific) */
1727
1728         lrt = LOCALREFTABLE;
1729
1730         /* go through all local frames */
1731
1732         for (; lrt != NULL; lrt = lrt->prev) {
1733
1734                 /* and try to remove the reference */
1735
1736                 for (i = 0; i < lrt->capacity; i++) {
1737                         if (lrt->refs[i] == o) {
1738                                 lrt->refs[i] = NULL;
1739                                 lrt->used--;
1740
1741                                 return;
1742                         }
1743                 }
1744         }
1745
1746         /* this should not happen */
1747
1748 /*      if (opt_checkjni) */
1749 /*      FatalError(env, "Bad global or local ref passed to JNI"); */
1750         log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
1751 }
1752
1753
1754 /* IsSameObject ****************************************************************
1755
1756    Tests whether two references refer to the same Java object.
1757
1758 *******************************************************************************/
1759
1760 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1761 {
1762         STATISTICS(jniinvokation());
1763
1764         if (ref1 == ref2)
1765                 return JNI_TRUE;
1766         else
1767                 return JNI_FALSE;
1768 }
1769
1770
1771 /* NewLocalRef *****************************************************************
1772
1773    Creates a new local reference that refers to the same object as ref.
1774
1775 *******************************************************************************/
1776
1777 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1778 {
1779         localref_table *lrt;
1780         s4              i;
1781
1782         STATISTICS(jniinvokation());
1783
1784         if (ref == NULL)
1785                 return NULL;
1786
1787         /* get local reference table (thread specific) */
1788
1789         lrt = LOCALREFTABLE;
1790
1791         /* Check if we have space for the requested reference?  No,
1792            allocate a new frame.  This is actually not what the spec says,
1793            but for compatibility reasons... */
1794
1795         if (lrt->used == lrt->capacity) {
1796                 if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
1797                         return NULL;
1798
1799                 /* get the new local reference table */
1800
1801                 lrt = LOCALREFTABLE;
1802         }
1803
1804         /* insert the reference */
1805
1806         for (i = 0; i < lrt->capacity; i++) {
1807                 if (lrt->refs[i] == NULL) {
1808                         lrt->refs[i] = (java_objectheader *) ref;
1809                         lrt->used++;
1810
1811                         return ref;
1812                 }
1813         }
1814
1815         /* should not happen, just to be sure */
1816
1817         assert(0);
1818
1819         /* keep compiler happy */
1820
1821         return NULL;
1822 }
1823
1824
1825 /* EnsureLocalCapacity *********************************************************
1826
1827    Ensures that at least a given number of local references can be
1828    created in the current thread
1829
1830 *******************************************************************************/
1831
1832 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1833 {
1834         localref_table *lrt;
1835
1836         STATISTICS(jniinvokation());
1837
1838         /* get local reference table (thread specific) */
1839
1840         lrt = LOCALREFTABLE;
1841
1842         /* check if capacity elements are available in the local references table */
1843
1844         if ((lrt->used + capacity) > lrt->capacity)
1845                 return _Jv_JNI_PushLocalFrame(env, capacity);
1846
1847         return 0;
1848 }
1849
1850
1851 /* AllocObject *****************************************************************
1852
1853    Allocates a new Java object without invoking any of the
1854    constructors for the object. Returns a reference to the object.
1855
1856 *******************************************************************************/
1857
1858 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1859 {
1860         classinfo         *c;
1861         java_objectheader *o;
1862
1863         STATISTICS(jniinvokation());
1864
1865         c = (classinfo *) clazz;
1866
1867         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1868                 exceptions_throw_instantiationexception(c);
1869                 return NULL;
1870         }
1871                 
1872         o = builtin_new(c);
1873
1874         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1875 }
1876
1877
1878 /* NewObject *******************************************************************
1879
1880    Programmers place all arguments that are to be passed to the
1881    constructor immediately following the methodID
1882    argument. NewObject() accepts these arguments and passes them to
1883    the Java method that the programmer wishes to invoke.
1884
1885 *******************************************************************************/
1886
1887 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1888 {
1889         java_objectheader *o;
1890         classinfo         *c;
1891         methodinfo        *m;
1892         va_list            ap;
1893
1894         STATISTICS(jniinvokation());
1895
1896         c = (classinfo *) clazz;
1897         m = (methodinfo *) methodID;
1898
1899         /* create object */
1900
1901         o = builtin_new(c);
1902         
1903         if (o == NULL)
1904                 return NULL;
1905
1906         /* call constructor */
1907
1908         va_start(ap, methodID);
1909         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1910         va_end(ap);
1911
1912         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1913 }
1914
1915
1916 /* NewObjectV ******************************************************************
1917
1918    Programmers place all arguments that are to be passed to the
1919    constructor in an args argument of type va_list that immediately
1920    follows the methodID argument. NewObjectV() accepts these
1921    arguments, and, in turn, passes them to the Java method that the
1922    programmer wishes to invoke.
1923
1924 *******************************************************************************/
1925
1926 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1927                                                    va_list args)
1928 {
1929         java_objectheader *o;
1930         classinfo         *c;
1931         methodinfo        *m;
1932
1933         STATISTICS(jniinvokation());
1934
1935         c = (classinfo *) clazz;
1936         m = (methodinfo *) methodID;
1937
1938         /* create object */
1939
1940         o = builtin_new(c);
1941         
1942         if (o == NULL)
1943                 return NULL;
1944
1945         /* call constructor */
1946
1947         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1948
1949         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1950 }
1951
1952
1953 /* NewObjectA ***************************************************************** 
1954
1955    Programmers place all arguments that are to be passed to the
1956    constructor in an args array of jvalues that immediately follows
1957    the methodID argument. NewObjectA() accepts the arguments in this
1958    array, and, in turn, passes them to the Java method that the
1959    programmer wishes to invoke.
1960
1961 *******************************************************************************/
1962
1963 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1964                                                    const jvalue *args)
1965 {
1966         java_objectheader *o;
1967         classinfo         *c;
1968         methodinfo        *m;
1969
1970         STATISTICS(jniinvokation());
1971
1972         c = (classinfo *) clazz;
1973         m = (methodinfo *) methodID;
1974
1975         /* create object */
1976
1977         o = builtin_new(c);
1978         
1979         if (o == NULL)
1980                 return NULL;
1981
1982         /* call constructor */
1983
1984         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1985
1986         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1987 }
1988
1989
1990 /* GetObjectClass **************************************************************
1991
1992  Returns the class of an object.
1993
1994 *******************************************************************************/
1995
1996 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1997 {
1998         java_objectheader *o;
1999         classinfo         *c;
2000
2001         STATISTICS(jniinvokation());
2002
2003         o = (java_objectheader *) obj;
2004
2005         if ((o == NULL) || (o->vftbl == NULL))
2006                 return NULL;
2007
2008         c = o->vftbl->class;
2009
2010         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
2011 }
2012
2013
2014 /* IsInstanceOf ****************************************************************
2015
2016    Tests whether an object is an instance of a class.
2017
2018 *******************************************************************************/
2019
2020 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
2021 {
2022         java_lang_Class  *c;
2023         java_lang_Object *o;
2024
2025         STATISTICS(jniinvokation());
2026
2027         c = (java_lang_Class *) clazz;
2028         o = (java_lang_Object *) obj;
2029
2030         return _Jv_java_lang_Class_isInstance(c, o);
2031 }
2032
2033
2034 /* Reflection Support *********************************************************/
2035
2036 /* FromReflectedMethod *********************************************************
2037
2038    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
2039    object to a method ID.
2040   
2041 *******************************************************************************/
2042   
2043 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
2044 {
2045 #if defined(ENABLE_JAVASE)
2046         java_objectheader *o;
2047         classinfo         *c;
2048         methodinfo        *m;
2049         s4                 slot;
2050
2051         STATISTICS(jniinvokation());
2052
2053         o = (java_objectheader *) method;
2054
2055         if (o == NULL)
2056                 return NULL;
2057         
2058         if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
2059                 java_lang_reflect_Method *rm;
2060
2061                 rm   = (java_lang_reflect_Method *) method;
2062                 c    = (classinfo *) (rm->clazz);
2063                 slot = rm->slot;
2064         }
2065         else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
2066                 java_lang_reflect_Constructor *rc;
2067
2068                 rc   = (java_lang_reflect_Constructor *) method;
2069                 c    = (classinfo *) (rc->clazz);
2070                 slot = rc->slot;
2071         }
2072         else
2073                 return NULL;
2074
2075         m = &(c->methods[slot]);
2076
2077         return (jmethodID) m;
2078 #else
2079         vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
2080
2081         /* keep compiler happy */
2082
2083         return NULL;
2084 #endif
2085 }
2086
2087
2088 /* FromReflectedField **********************************************************
2089
2090    Converts a java.lang.reflect.Field to a field ID.
2091
2092 *******************************************************************************/
2093  
2094 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
2095 {
2096 #if defined(ENABLE_JAVASE)
2097         java_lang_reflect_Field *rf;
2098         classinfo               *c;
2099         fieldinfo               *f;
2100
2101         STATISTICS(jniinvokation());
2102
2103         rf = (java_lang_reflect_Field *) field;
2104
2105         if (rf == NULL)
2106                 return NULL;
2107
2108         c = (classinfo *) rf->clazz;
2109         f = &(c->fields[rf->slot]);
2110
2111         return (jfieldID) f;
2112 #else
2113         vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
2114
2115         /* keep compiler happy */
2116
2117         return NULL;
2118 #endif
2119 }
2120
2121
2122 /* ToReflectedMethod ***********************************************************
2123
2124    Converts a method ID derived from cls to an instance of the
2125    java.lang.reflect.Method class or to an instance of the
2126    java.lang.reflect.Constructor class.
2127
2128 *******************************************************************************/
2129
2130 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
2131                                                                   jboolean isStatic)
2132 {
2133 #if defined(ENABLE_JAVASE)
2134         methodinfo                    *m;
2135         java_lang_reflect_Constructor *rc;
2136         java_lang_reflect_Method      *rm;
2137
2138         STATISTICS(jniinvokation());
2139
2140         m = (methodinfo *) methodID;
2141
2142         /* HotSpot does the same assert. */
2143
2144         assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
2145
2146         if (m->name == utf_init) {
2147                 rc = reflect_constructor_new(m);
2148
2149                 return (jobject) rc;
2150         }
2151         else {
2152                 rm = reflect_method_new(m);
2153
2154                 return (jobject) rm;
2155         }
2156 #else
2157         vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
2158
2159         /* keep compiler happy */
2160
2161         return NULL;
2162 #endif
2163 }
2164
2165
2166 /* ToReflectedField ************************************************************
2167
2168    Converts a field ID derived from cls to an instance of the
2169    java.lang.reflect.Field class.
2170
2171 *******************************************************************************/
2172
2173 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
2174                                                                  jboolean isStatic)
2175 {
2176         STATISTICS(jniinvokation());
2177
2178         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
2179
2180         return NULL;
2181 }
2182
2183
2184 /* Calling Instance Methods ***************************************************/
2185
2186 /* GetMethodID *****************************************************************
2187
2188    Returns the method ID for an instance (nonstatic) method of a class
2189    or interface. The method may be defined in one of the clazz's
2190    superclasses and inherited by clazz. The method is determined by
2191    its name and signature.
2192
2193    GetMethodID() causes an uninitialized class to be initialized.
2194
2195 *******************************************************************************/
2196
2197 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
2198                                                           const char *sig)
2199 {
2200         classinfo  *c;
2201         utf        *uname;
2202         utf        *udesc;
2203         methodinfo *m;
2204
2205         STATISTICS(jniinvokation());
2206
2207         c = (classinfo *) clazz;
2208
2209         if (c == NULL)
2210                 return NULL;
2211
2212         if (!(c->state & CLASS_INITIALIZED))
2213                 if (!initialize_class(c))
2214                         return NULL;
2215
2216         /* try to get the method of the class or one of it's superclasses */
2217
2218         uname = utf_new_char((char *) name);
2219         udesc = utf_new_char((char *) sig);
2220
2221         m = class_resolvemethod(c, uname, udesc);
2222
2223         if ((m == NULL) || (m->flags & ACC_STATIC)) {
2224                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2225
2226                 return NULL;
2227         }
2228
2229         return (jmethodID) m;
2230 }
2231
2232
2233 /* JNI-functions for calling instance methods *********************************/
2234
2235 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2236                                                                  ...)
2237 {
2238         java_objectheader *o;
2239         methodinfo        *m;
2240         java_objectheader *ret;
2241         va_list            ap;
2242
2243         o = (java_objectheader *) obj;
2244         m = (methodinfo *) methodID;
2245
2246         va_start(ap, methodID);
2247         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
2248         va_end(ap);
2249
2250         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2251 }
2252
2253
2254 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2255                                                                   va_list args)
2256 {
2257         java_objectheader *o;
2258         methodinfo        *m;
2259         java_objectheader *ret;
2260
2261         o = (java_objectheader *) obj;
2262         m = (methodinfo *) methodID;
2263
2264         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
2265
2266         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2267 }
2268
2269
2270 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2271                                                                   const jvalue *args)
2272 {
2273         java_objectheader *o;
2274         methodinfo        *m;
2275         java_objectheader *ret;
2276
2277         o = (java_objectheader *) obj;
2278         m = (methodinfo *) methodID;
2279
2280         ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
2281
2282         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
2283 }
2284
2285
2286 jboolean _Jv_JNI_CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2287                                                                    ...)
2288 {
2289         java_objectheader *o;
2290         methodinfo        *m;
2291         va_list            ap;
2292         jboolean           b;
2293
2294         o = (java_objectheader *) obj;
2295         m = (methodinfo *) methodID;
2296
2297         va_start(ap, methodID);
2298         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2299         va_end(ap);
2300
2301         return b;
2302 }
2303
2304
2305 jboolean _Jv_JNI_CallBooleanMethodV(JNIEnv *env, jobject obj,
2306                                                                         jmethodID methodID, va_list args)
2307 {
2308         java_objectheader *o;
2309         methodinfo        *m;
2310         jboolean           b;
2311
2312         o = (java_objectheader *) obj;
2313         m = (methodinfo *) methodID;
2314
2315         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2316
2317         return b;
2318 }
2319
2320
2321 jboolean _Jv_JNI_CallBooleanMethodA(JNIEnv *env, jobject obj,
2322                                                                         jmethodID methodID, const jvalue *args)
2323 {
2324         java_objectheader *o;
2325         methodinfo        *m;
2326         jboolean           b;
2327
2328         o = (java_objectheader *) obj;
2329         m = (methodinfo *) methodID;
2330
2331         b = _Jv_jni_CallIntMethodA(o, o->vftbl, m, args);
2332
2333         return b;
2334 }
2335
2336
2337 jbyte _Jv_JNI_CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2338 {
2339         java_objectheader *o;
2340         methodinfo        *m;
2341         va_list            ap;
2342         jbyte              b;
2343
2344         o = (java_objectheader *) obj;
2345         m = (methodinfo *) methodID;
2346
2347         va_start(ap, methodID);
2348         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2349         va_end(ap);
2350
2351         return b;
2352
2353 }
2354
2355
2356 jbyte _Jv_JNI_CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2357                                                           va_list args)
2358 {
2359         java_objectheader *o;
2360         methodinfo        *m;
2361         jbyte              b;
2362
2363         o = (java_objectheader *) obj;
2364         m = (methodinfo *) methodID;
2365
2366         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2367
2368         return b;
2369 }
2370
2371
2372 jbyte _Jv_JNI_CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2373                                                           const jvalue *args)
2374 {
2375         log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
2376
2377         return 0;
2378 }
2379
2380
2381 jchar _Jv_JNI_CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2382 {
2383         java_objectheader *o;
2384         methodinfo        *m;
2385         va_list            ap;
2386         jchar              c;
2387
2388         o = (java_objectheader *) obj;
2389         m = (methodinfo *) methodID;
2390
2391         va_start(ap, methodID);
2392         c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2393         va_end(ap);
2394
2395         return c;
2396 }
2397
2398
2399 jchar _Jv_JNI_CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2400                                                           va_list args)
2401 {
2402         java_objectheader *o;
2403         methodinfo        *m;
2404         jchar              c;
2405
2406         o = (java_objectheader *) obj;
2407         m = (methodinfo *) methodID;
2408
2409         c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2410
2411         return c;
2412 }
2413
2414
2415 jchar _Jv_JNI_CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2416                                                           const jvalue *args)
2417 {
2418         log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
2419
2420         return 0;
2421 }
2422
2423
2424 jshort _Jv_JNI_CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2425                                                            ...)
2426 {
2427         java_objectheader *o;
2428         methodinfo        *m;
2429         va_list            ap;
2430         jshort             s;
2431
2432         o = (java_objectheader *) obj;
2433         m = (methodinfo *) methodID;
2434
2435         va_start(ap, methodID);
2436         s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2437         va_end(ap);
2438
2439         return s;
2440 }
2441
2442
2443 jshort _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2444                                                                 va_list args)
2445 {
2446         java_objectheader *o;
2447         methodinfo        *m;
2448         jshort             s;
2449
2450         o = (java_objectheader *) obj;
2451         m = (methodinfo *) methodID;
2452
2453         s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2454
2455         return s;
2456 }
2457
2458
2459 jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2460                                                                 const jvalue *args)
2461 {
2462         log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
2463
2464         return 0;
2465 }
2466
2467
2468
2469 jint _Jv_JNI_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2470 {
2471         java_objectheader *o;
2472         methodinfo        *m;
2473         va_list            ap;
2474         jint               i;
2475
2476         o = (java_objectheader *) obj;
2477         m = (methodinfo *) methodID;
2478
2479         va_start(ap, methodID);
2480         i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
2481         va_end(ap);
2482
2483         return i;
2484 }
2485
2486
2487 jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2488                                                         va_list args)
2489 {
2490         java_objectheader *o;
2491         methodinfo        *m;
2492         jint               i;
2493
2494         o = (java_objectheader *) obj;
2495         m = (methodinfo *) methodID;
2496
2497         i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2498
2499         return i;
2500 }
2501
2502
2503 jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2504                                                         const jvalue *args)
2505 {
2506         log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2507
2508         return 0;
2509 }
2510
2511
2512
2513 jlong _Jv_JNI_CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2514 {
2515         java_objectheader *o;
2516         methodinfo        *m;
2517         va_list            ap;
2518         jlong              l;
2519
2520         o = (java_objectheader *) obj;
2521         m = (methodinfo *) methodID;
2522
2523         va_start(ap, methodID);
2524         l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2525         va_end(ap);
2526
2527         return l;
2528 }
2529
2530
2531 jlong _Jv_JNI_CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2532                                                           va_list args)
2533 {
2534         java_objectheader *o;
2535         methodinfo        *m;
2536         jlong              l;
2537
2538         o = (java_objectheader *) obj;
2539         m = (methodinfo *) methodID;
2540
2541         l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2542
2543         return l;
2544 }
2545
2546
2547 jlong _Jv_JNI_CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2548                                                           const jvalue *args)
2549 {
2550         log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2551
2552         return 0;
2553 }
2554
2555
2556
2557 jfloat _Jv_JNI_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2558                                                            ...)
2559 {
2560         java_objectheader *o;
2561         methodinfo        *m;
2562         va_list            ap;
2563         jfloat             f;
2564
2565         o = (java_objectheader *) obj;
2566         m = (methodinfo *) methodID;
2567
2568         va_start(ap, methodID);
2569         f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2570         va_end(ap);
2571
2572         return f;
2573 }
2574
2575
2576 jfloat _Jv_JNI_CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2577                                                                 va_list args)
2578 {
2579         java_objectheader *o;
2580         methodinfo        *m;
2581         jfloat             f;
2582
2583         o = (java_objectheader *) obj;
2584         m = (methodinfo *) methodID;
2585
2586         f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2587
2588         return f;
2589 }
2590
2591
2592 jfloat _Jv_JNI_CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2593                                                                 const jvalue *args)
2594 {
2595         log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2596
2597         return 0;
2598 }
2599
2600
2601
2602 jdouble _Jv_JNI_CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID,
2603                                                                  ...)
2604 {
2605         java_objectheader *o;
2606         methodinfo        *m;
2607         va_list            ap;
2608         jdouble            d;
2609
2610         o = (java_objectheader *) obj;
2611         m = (methodinfo *) methodID;
2612
2613         va_start(ap, methodID);
2614         d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2615         va_end(ap);
2616
2617         return d;
2618 }
2619
2620
2621 jdouble _Jv_JNI_CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2622                                                                   va_list args)
2623 {
2624         java_objectheader *o;
2625         methodinfo        *m;
2626         jdouble            d;
2627
2628         o = (java_objectheader *) obj;
2629         m = (methodinfo *) methodID;
2630
2631         d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2632
2633         return d;
2634 }
2635
2636
2637 jdouble _Jv_JNI_CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2638                                                                   const jvalue *args)
2639 {
2640         log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2641
2642         return 0;
2643 }
2644
2645
2646
2647 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2648 {
2649         java_objectheader *o;
2650         methodinfo        *m;
2651         va_list            ap;
2652
2653         o = (java_objectheader *) obj;
2654         m = (methodinfo *) methodID;
2655
2656         va_start(ap, methodID);
2657         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2658         va_end(ap);
2659 }
2660
2661
2662 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
2663                                                          va_list args)
2664 {
2665         java_objectheader *o;
2666         methodinfo        *m;
2667
2668         o = (java_objectheader *) obj;
2669         m = (methodinfo *) methodID;
2670
2671         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2672 }
2673
2674
2675 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
2676                                                          const jvalue *args)
2677 {
2678         java_objectheader *o;
2679         methodinfo        *m;
2680
2681         o = (java_objectheader *) obj;
2682         m = (methodinfo *) methodID;
2683
2684         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2685 }
2686
2687
2688
2689 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2690                                                                                    jclass clazz, jmethodID methodID,
2691                                                                                    ...)
2692 {
2693         java_objectheader *o;
2694         classinfo         *c;
2695         methodinfo        *m;
2696         java_objectheader *r;
2697         va_list            ap;
2698
2699         o = (java_objectheader *) obj;
2700         c = (classinfo *) clazz;
2701         m = (methodinfo *) methodID;
2702
2703         va_start(ap, methodID);
2704         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2705         va_end(ap);
2706
2707         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2708 }
2709
2710
2711 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2712                                                                                         jclass clazz, jmethodID methodID,
2713                                                                                         va_list args)
2714 {
2715         java_objectheader *o;
2716         classinfo         *c;
2717         methodinfo        *m;
2718         java_objectheader *r;
2719
2720         o = (java_objectheader *) obj;
2721         c = (classinfo *) clazz;
2722         m = (methodinfo *) methodID;
2723
2724         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2725
2726         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2727 }
2728
2729
2730 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2731                                                                                         jclass clazz, jmethodID methodID,
2732                                                                                         const jvalue *args)
2733 {
2734         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2735
2736         return _Jv_JNI_NewLocalRef(env, NULL);
2737 }
2738
2739
2740
2741 jboolean _Jv_JNI_CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj,
2742                                                                                          jclass clazz, jmethodID methodID,
2743                                                                                          ...)
2744 {
2745         java_objectheader *o;
2746         classinfo         *c;
2747         methodinfo        *m;
2748         va_list            ap;
2749         jboolean           b;
2750
2751         o = (java_objectheader *) obj;
2752         c = (classinfo *) clazz;
2753         m = (methodinfo *) methodID;
2754
2755         va_start(ap, methodID);
2756         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2757         va_end(ap);
2758
2759         return b;
2760 }
2761
2762
2763 jboolean _Jv_JNI_CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj,
2764                                                                                           jclass clazz, jmethodID methodID,
2765                                                                                           va_list args)
2766 {
2767         java_objectheader *o;
2768         classinfo         *c;
2769         methodinfo        *m;
2770         jboolean           b;
2771
2772         o = (java_objectheader *) obj;
2773         c = (classinfo *) clazz;
2774         m = (methodinfo *) methodID;
2775
2776         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2777
2778         return b;
2779 }
2780
2781
2782 jboolean _Jv_JNI_CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj,
2783                                                                                           jclass clazz, jmethodID methodID,
2784                                                                                           const jvalue *args)
2785 {
2786         log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2787
2788         return 0;
2789 }
2790
2791
2792 jbyte _Jv_JNI_CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz,
2793                                                                            jmethodID methodID, ...)
2794 {
2795         java_objectheader *o;
2796         classinfo         *c;
2797         methodinfo        *m;
2798         va_list            ap;
2799         jbyte              b;
2800
2801         o = (java_objectheader *) obj;
2802         c = (classinfo *) clazz;
2803         m = (methodinfo *) methodID;
2804
2805         va_start(ap, methodID);
2806         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2807         va_end(ap);
2808
2809         return b;
2810 }
2811
2812
2813 jbyte _Jv_JNI_CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz,
2814                                                                                 jmethodID methodID, va_list args)
2815 {
2816         java_objectheader *o;
2817         classinfo         *c;
2818         methodinfo        *m;
2819         jbyte              b;
2820
2821         o = (java_objectheader *) obj;
2822         c = (classinfo *) clazz;
2823         m = (methodinfo *) methodID;
2824
2825         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2826
2827         return b;
2828 }
2829
2830
2831 jbyte _Jv_JNI_CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, 
2832                                                                                 jmethodID methodID, const jvalue *args)
2833 {
2834         log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2835
2836         return 0;
2837 }
2838
2839
2840
2841 jchar _Jv_JNI_CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz,
2842                                                                            jmethodID methodID, ...)
2843 {
2844         java_objectheader *o;
2845         classinfo         *c;
2846         methodinfo        *m;
2847         va_list            ap;
2848         jchar              ch;
2849
2850         o = (java_objectheader *) obj;
2851         c = (classinfo *) clazz;
2852         m = (methodinfo *) methodID;
2853
2854         va_start(ap, methodID);
2855         ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2856         va_end(ap);
2857
2858         return ch;
2859 }
2860
2861
2862 jchar _Jv_JNI_CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz,
2863                                                                                 jmethodID methodID, va_list args)
2864 {
2865         java_objectheader *o;
2866         classinfo         *c;
2867         methodinfo        *m;
2868         jchar              ch;
2869
2870         o = (java_objectheader *) obj;
2871         c = (classinfo *) clazz;
2872         m = (methodinfo *) methodID;
2873
2874         ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2875
2876         return ch;
2877 }
2878
2879
2880 jchar _Jv_JNI_CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz,
2881                                                                                 jmethodID methodID, const jvalue *args)
2882 {
2883         log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2884
2885         return 0;
2886 }
2887
2888
2889
2890 jshort _Jv_JNI_CallNonvirtualShortMethod(JNIEnv *env, jobject obj,
2891                                                                                  jclass clazz, jmethodID methodID, ...)
2892 {
2893         java_objectheader *o;
2894         classinfo         *c;
2895         methodinfo        *m;
2896         va_list            ap;
2897         jshort             s;
2898
2899         o = (java_objectheader *) obj;
2900         c = (classinfo *) clazz;
2901         m = (methodinfo *) methodID;
2902
2903         va_start(ap, methodID);
2904         s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2905         va_end(ap);
2906
2907         return s;
2908 }
2909
2910
2911 jshort _Jv_JNI_CallNonvirtualShortMethodV(JNIEnv *env, jobject obj,
2912                                                                                   jclass clazz, jmethodID methodID,
2913                                                                                   va_list args)
2914 {
2915         java_objectheader *o;
2916         classinfo         *c;
2917         methodinfo        *m;
2918         jshort             s;
2919
2920         o = (java_objectheader *) obj;
2921         c = (classinfo *) clazz;
2922         m = (methodinfo *) methodID;
2923
2924         s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2925
2926         return s;
2927 }
2928
2929
2930 jshort _Jv_JNI_CallNonvirtualShortMethodA(JNIEnv *env, jobject obj,
2931                                                                                   jclass clazz, jmethodID methodID,
2932                                                                                   const jvalue *args)
2933 {
2934         log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2935
2936         return 0;
2937 }
2938
2939
2940
2941 jint _Jv_JNI_CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz,
2942                                                                          jmethodID methodID, ...)
2943 {
2944         java_objectheader *o;
2945         classinfo         *c;
2946         methodinfo        *m;
2947         va_list            ap;
2948         jint               i;
2949
2950         o = (java_objectheader *) obj;
2951         c = (classinfo *) clazz;
2952         m = (methodinfo *) methodID;
2953
2954         va_start(ap, methodID);
2955         i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2956         va_end(ap);
2957
2958         return i;
2959 }
2960
2961
2962 jint _Jv_JNI_CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz,
2963                                                                           jmethodID methodID, va_list args)
2964 {
2965         java_objectheader *o;
2966         classinfo         *c;
2967         methodinfo        *m;
2968         jint               i;
2969
2970         o = (java_objectheader *) obj;
2971         c = (classinfo *) clazz;
2972         m = (methodinfo *) methodID;
2973
2974         i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2975
2976         return i;
2977 }
2978
2979
2980 jint _Jv_JNI_CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz,
2981                                                                           jmethodID methodID, const jvalue *args)
2982 {
2983         log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2984
2985         return 0;
2986 }
2987
2988
2989
2990 jlong _Jv_JNI_CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz,
2991                                                                            jmethodID methodID, ...)
2992 {
2993         java_objectheader *o;
2994         classinfo         *c;
2995         methodinfo        *m;
2996         va_list            ap;
2997         jlong              l;
2998
2999         o = (java_objectheader *) obj;
3000         c = (classinfo *) clazz;
3001         m = (methodinfo *) methodID;
3002
3003         va_start(ap, methodID);
3004         l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
3005         va_end(ap);
3006
3007         return l;
3008 }
3009
3010
3011 jlong _Jv_JNI_CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz,
3012                                                                                 jmethodID methodID, va_list args)
3013 {
3014         java_objectheader *o;
3015         classinfo         *c;
3016         methodinfo        *m;
3017         jlong              l;
3018
3019         o = (java_objectheader *) obj;
3020         c = (classinfo *) clazz;
3021         m = (methodinfo *) methodID;
3022
3023         l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
3024
3025         return l;
3026 }
3027
3028
3029 jlong _Jv_JNI_CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz,
3030                                                                                 jmethodID methodID, const jvalue *args)
3031 {
3032         log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
3033
3034         return 0;
3035 }
3036
3037
3038
3039 jfloat _Jv_JNI_CallNonvirtualFloatMethod(JNIEnv *env, jobject obj,
3040                                                                                  jclass clazz, jmethodID methodID, ...)
3041 {
3042         java_objectheader *o;
3043         classinfo         *c;
3044         methodinfo        *m;
3045         va_list            ap;
3046         jfloat             f;
3047
3048         o = (java_objectheader *) obj;
3049         c = (classinfo *) clazz;
3050         m = (methodinfo *) methodID;
3051
3052         va_start(ap, methodID);
3053         f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
3054         va_end(ap);
3055
3056         return f;
3057 }
3058
3059
3060 jfloat _Jv_JNI_CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj,
3061                                                                                   jclass clazz, jmethodID methodID,
3062                                                                                   va_list args)
3063 {
3064         java_objectheader *o;
3065         classinfo         *c;
3066         methodinfo        *m;
3067         jfloat             f;
3068
3069         o = (java_objectheader *) obj;
3070         c = (classinfo *) clazz;
3071         m = (methodinfo *) methodID;
3072
3073         f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
3074
3075         return f;
3076 }
3077
3078
3079 jfloat _Jv_JNI_CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj,
3080                                                                                   jclass clazz, jmethodID methodID,
3081                                                                                   const jvalue *args)
3082 {
3083         log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
3084
3085         return 0;
3086 }
3087
3088
3089
3090 jdouble _Jv_JNI_CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj,
3091                                                                                    jclass clazz, jmethodID methodID,
3092                                                                                    ...)
3093 {
3094         java_objectheader *o;
3095         classinfo         *c;
3096         methodinfo        *m;
3097         va_list            ap;
3098         jdouble            d;
3099
3100         o = (java_objectheader *) obj;
3101         c = (classinfo *) clazz;
3102         m = (methodinfo *) methodID;
3103
3104         va_start(ap, methodID);
3105         d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
3106         va_end(ap);
3107
3108         return d;
3109 }
3110
3111
3112 jdouble _Jv_JNI_CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj,
3113                                                                                         jclass clazz, jmethodID methodID,
3114                                                                                         va_list args)
3115 {
3116         java_objectheader *o;
3117         classinfo         *c;
3118         methodinfo        *m;
3119         jdouble            d;
3120
3121         o = (java_objectheader *) obj;
3122         c = (classinfo *) clazz;
3123         m = (methodinfo *) methodID;
3124
3125         d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
3126
3127         return d;
3128 }
3129
3130
3131 jdouble _Jv_JNI_CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj,
3132                                                                                         jclass clazz, jmethodID methodID,
3133                                                                                         const jvalue *args)
3134 {
3135         log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
3136
3137         return 0;
3138 }
3139
3140
3141
3142 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
3143                                                                           jmethodID methodID, ...)
3144 {
3145         java_objectheader *o;
3146         classinfo         *c;
3147         methodinfo        *m;
3148         va_list            ap;
3149
3150         o = (java_objectheader *) obj;
3151         c = (classinfo *) clazz;
3152         m = (methodinfo *) methodID;
3153
3154         va_start(ap, methodID);
3155         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
3156         va_end(ap);
3157 }
3158
3159
3160 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
3161                                                                            jmethodID methodID, va_list args)
3162 {
3163         java_objectheader *o;
3164         classinfo         *c;
3165         methodinfo        *m;
3166
3167         o = (java_objectheader *) obj;
3168         c = (classinfo *) clazz;
3169         m = (methodinfo *) methodID;
3170
3171         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
3172 }
3173
3174
3175 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
3176                                                                            jmethodID methodID, const jvalue * args)
3177 {       
3178         java_objectheader *o;
3179         classinfo         *c;
3180         methodinfo        *m;
3181
3182         o = (java_objectheader *) obj;
3183         c = (classinfo *) clazz;
3184         m = (methodinfo *) methodID;
3185
3186         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
3187 }
3188
3189
3190 /* Accessing Fields of Objects ************************************************/
3191
3192 /* GetFieldID ******************************************************************
3193
3194    Returns the field ID for an instance (nonstatic) field of a
3195    class. The field is specified by its name and signature. The
3196    Get<type>Field and Set<type>Field families of accessor functions
3197    use field IDs to retrieve object fields.
3198
3199 *******************************************************************************/
3200
3201 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
3202                                                         const char *sig)
3203 {
3204         classinfo *c;
3205         fieldinfo *f;
3206         utf       *uname;
3207         utf       *udesc;
3208
3209         STATISTICS(jniinvokation());
3210
3211         c = (classinfo *) clazz;
3212
3213         /* XXX NPE check? */
3214
3215         uname = utf_new_char((char *) name);
3216         udesc = utf_new_char((char *) sig);
3217
3218         f = class_findfield(c, uname, udesc); 
3219         
3220         if (f == NULL)
3221                 exceptions_throw_nosuchfielderror(c, uname);  
3222
3223         return (jfieldID) f;
3224 }
3225
3226
3227 /* Get<type>Field Routines *****************************************************
3228
3229    This family of accessor routines returns the value of an instance
3230    (nonstatic) field of an object. The field to access is specified by
3231    a field ID obtained by calling GetFieldID().
3232
3233 *******************************************************************************/
3234
3235 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
3236 {
3237         java_objectheader *o;
3238
3239         STATISTICS(jniinvokation());
3240
3241         o = GET_FIELD(obj, java_objectheader*, fieldID);
3242
3243         return _Jv_JNI_NewLocalRef(env, (jobject) o);
3244 }
3245
3246
3247 jboolean _Jv_JNI_GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
3248 {
3249         s4 i;
3250
3251         STATISTICS(jniinvokation());
3252
3253         i = GET_FIELD(obj, s4, fieldID);
3254
3255         return (jboolean) i;
3256 }
3257
3258
3259 jbyte _Jv_JNI_GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
3260 {
3261         s4 i;
3262
3263         STATISTICS(jniinvokation());
3264
3265         i = GET_FIELD(obj, s4, fieldID);
3266
3267         return (jbyte) i;
3268 }
3269
3270
3271 jchar _Jv_JNI_GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
3272 {
3273         s4 i;
3274
3275         STATISTICS(jniinvokation());
3276
3277         i = GET_FIELD(obj, s4, fieldID);
3278
3279         return (jchar) i;
3280 }
3281
3282
3283 jshort _Jv_JNI_GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
3284 {
3285         s4 i;
3286
3287         STATISTICS(jniinvokation());
3288
3289         i = GET_FIELD(obj, s4, fieldID);
3290
3291         return (jshort) i;
3292 }
3293
3294
3295 jint _Jv_JNI_GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
3296 {
3297         java_objectheader *o;
3298         fieldinfo         *f;
3299         s4                 i;
3300
3301         STATISTICS(jniinvokation());
3302
3303         o = (java_objectheader *) obj;
3304         f = (fieldinfo *) fieldID;
3305
3306         i = GET_FIELD(o, s4, f);
3307
3308         return i;
3309 }
3310
3311
3312 jlong _Jv_JNI_GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
3313 {
3314         s8 l;
3315
3316         STATISTICS(jniinvokation());
3317
3318         l = GET_FIELD(obj, s8, fieldID);
3319
3320         return l;
3321 }
3322
3323
3324 jfloat _Jv_JNI_GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
3325 {
3326         float f;
3327
3328         STATISTICS(jniinvokation());
3329
3330         f = GET_FIELD(obj, float, fieldID);
3331
3332         return f;
3333 }
3334
3335
3336 jdouble _Jv_JNI_GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
3337 {
3338         double d;
3339
3340         STATISTICS(jniinvokation());
3341
3342         d = GET_FIELD(obj, double, fieldID);
3343
3344         return d;
3345 }
3346
3347
3348 /* Set<type>Field Routines *****************************************************
3349
3350    This family of accessor routines sets the value of an instance
3351    (nonstatic) field of an object. The field to access is specified by
3352    a field ID obtained by calling GetFieldID().
3353
3354 *******************************************************************************/
3355
3356 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
3357                                                         jobject value)
3358 {
3359         STATISTICS(jniinvokation());
3360
3361         SET_FIELD(obj, java_objectheader*, fieldID, value);
3362 }
3363
3364
3365 void _Jv_JNI_SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
3366                                                          jboolean value)
3367 {
3368         STATISTICS(jniinvokation());
3369
3370         SET_FIELD(obj, s4, fieldID, value);
3371 }
3372
3373
3374 void _Jv_JNI_SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID,
3375                                                   jbyte value)
3376 {
3377         STATISTICS(jniinvokation());
3378
3379         SET_FIELD(obj, s4, fieldID, value);
3380 }
3381
3382
3383 void _Jv_JNI_SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID,
3384                                                   jchar value)
3385 {
3386         STATISTICS(jniinvokation());
3387
3388         SET_FIELD(obj, s4, fieldID, value);
3389 }
3390
3391
3392 void _Jv_JNI_SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID,
3393                                                    jshort value)
3394 {
3395         STATISTICS(jniinvokation());
3396
3397         SET_FIELD(obj, s4, fieldID, value);
3398 }
3399
3400
3401 void _Jv_JNI_SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
3402 {
3403         STATISTICS(jniinvokation());
3404
3405         SET_FIELD(obj, s4, fieldID, value);
3406 }
3407
3408
3409 void _Jv_JNI_SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID,
3410                                                   jlong value)
3411 {
3412         STATISTICS(jniinvokation());
3413
3414         SET_FIELD(obj, s8, fieldID, value);
3415 }
3416
3417
3418 void _Jv_JNI_SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID,
3419                                                    jfloat value)
3420 {
3421         STATISTICS(jniinvokation());
3422
3423         SET_FIELD(obj, float, fieldID, value);
3424 }
3425
3426
3427 void _Jv_JNI_SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID,
3428                                                         jdouble value)
3429 {
3430         STATISTICS(jniinvokation());
3431
3432         SET_FIELD(obj, double, fieldID, value);
3433 }
3434
3435
3436 /* Calling Static Methods *****************************************************/
3437
3438 /* GetStaticMethodID ***********************************************************
3439
3440    Returns the method ID for a static method of a class. The method is
3441    specified by its name and signature.
3442
3443    GetStaticMethodID() causes an uninitialized class to be
3444    initialized.
3445
3446 *******************************************************************************/
3447
3448 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
3449                                                                         const char *sig)
3450 {
3451         classinfo  *c;
3452         utf        *uname;
3453         utf        *udesc;
3454         methodinfo *m;
3455
3456         STATISTICS(jniinvokation());
3457
3458         c = (classinfo *) clazz;
3459
3460         if (!c)
3461                 return NULL;
3462
3463         if (!(c->state & CLASS_INITIALIZED))
3464                 if (!initialize_class(c))
3465                         return NULL;
3466
3467         /* try to get the static method of the class */
3468
3469         uname = utf_new_char((char *) name);
3470         udesc = utf_new_char((char *) sig);
3471
3472         m = class_resolvemethod(c, uname, udesc);
3473
3474         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
3475                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
3476
3477                 return NULL;
3478         }
3479
3480         return (jmethodID) m;
3481 }
3482
3483
3484 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
3485                                                                            jmethodID methodID, ...)
3486 {
3487         methodinfo        *m;
3488         java_objectheader *o;
3489         va_list            ap;
3490
3491         m = (methodinfo *) methodID;
3492
3493         va_start(ap, methodID);
3494         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
3495         va_end(ap);
3496
3497         return _Jv_JNI_NewLocalRef(env, (jobject) o);
3498 }
3499
3500
3501 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
3502                                                                                 jmethodID methodID, va_list args)
3503 {
3504         methodinfo        *m;
3505         java_objectheader *o;
3506
3507         m = (methodinfo *) methodID;
3508
3509         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
3510
3511         return _Jv_JNI_NewLocalRef(env, (jobject) o);
3512 }
3513
3514
3515 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
3516                                                                                 jmethodID methodID, const jvalue *args)
3517 {
3518         methodinfo        *m;
3519         java_objectheader *o;
3520
3521         m = (methodinfo *) methodID;
3522
3523         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
3524
3525         return _Jv_JNI_NewLocalRef(env, (jobject) o);
3526 }
3527
3528
3529 jboolean _Jv_JNI_CallStaticBooleanMethod(JNIEnv *env, jclass clazz,
3530                                                                                  jmethodID methodID, ...)
3531 {
3532         methodinfo *m;
3533         va_list     ap;
3534         jboolean    b;
3535
3536         m = (methodinfo *) methodID;
3537
3538         va_start(ap, methodID);
3539         b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3540         va_end(ap);
3541
3542         return b;
3543 }
3544
3545
3546 jboolean _Jv_JNI_CallStaticBooleanMethodV(JNIEnv *env, jclass clazz,
3547                                                                                   jmethodID methodID, va_list args)
3548 {
3549         methodinfo *m;
3550         jboolean    b;
3551
3552         m = (methodinfo *) methodID;
3553
3554         b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3555
3556         return b;
3557 }
3558
3559
3560 jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz,
3561                                                                                   jmethodID methodID, const jvalue *args)
3562 {
3563         methodinfo *m;
3564         jboolean    b;
3565
3566         m = (methodinfo *) methodID;
3567
3568         b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3569
3570         return b;
3571 }
3572
3573
3574 jbyte _Jv_JNI_CallStaticByteMethod(JNIEnv *env, jclass clazz,
3575                                                                    jmethodID methodID, ...)
3576 {
3577         methodinfo *m;
3578         va_list     ap;
3579         jbyte       b;
3580
3581         m = (methodinfo *) methodID;
3582
3583         va_start(ap, methodID);
3584         b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3585         va_end(ap);
3586
3587         return b;
3588 }
3589
3590
3591 jbyte _Jv_JNI_CallStaticByteMethodV(JNIEnv *env, jclass clazz,
3592                                                                         jmethodID methodID, va_list args)
3593 {
3594         methodinfo *m;
3595         jbyte       b;
3596
3597         m = (methodinfo *) methodID;
3598
3599         b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3600
3601         return b;
3602 }
3603
3604
3605 jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz,
3606                                                                         jmethodID methodID, const jvalue *args)
3607 {
3608         methodinfo *m;
3609         jbyte       b;
3610
3611         m = (methodinfo *) methodID;
3612
3613         b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3614
3615         return b;
3616 }
3617
3618
3619 jchar _Jv_JNI_CallStaticCharMethod(JNIEnv *env, jclass clazz,
3620                                                                    jmethodID methodID, ...)
3621 {
3622         methodinfo *m;
3623         va_list     ap;
3624         jchar       c;
3625
3626         m = (methodinfo *) methodID;
3627
3628         va_start(ap, methodID);
3629         c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3630         va_end(ap);
3631
3632         return c;
3633 }
3634
3635
3636 jchar _Jv_JNI_CallStaticCharMethodV(JNIEnv *env, jclass clazz,
3637                                                                         jmethodID methodID, va_list args)
3638 {
3639         methodinfo *m;
3640         jchar       c;
3641
3642         m = (methodinfo *) methodID;
3643
3644         c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3645
3646         return c;
3647 }
3648
3649
3650 jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz,
3651                                                                         jmethodID methodID, const jvalue *args)
3652 {
3653         methodinfo *m;
3654         jchar       c;
3655
3656         m = (methodinfo *) methodID;
3657
3658         c = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3659
3660         return c;
3661 }
3662
3663
3664 jshort _Jv_JNI_CallStaticShortMethod(JNIEnv *env, jclass clazz,
3665                                                                          jmethodID methodID, ...)
3666 {
3667         methodinfo *m;
3668         va_list     ap;
3669         jshort      s;
3670
3671         m = (methodinfo *) methodID;
3672
3673         va_start(ap, methodID);
3674         s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3675         va_end(ap);
3676
3677         return s;
3678 }
3679
3680
3681 jshort _Jv_JNI_CallStaticShortMethodV(JNIEnv *env, jclass clazz,
3682                                                                           jmethodID methodID, va_list args)
3683 {
3684         methodinfo *m;
3685         jshort      s;
3686
3687         m = (methodinfo *) methodID;
3688
3689         s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3690
3691         return s;
3692 }
3693
3694
3695 jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz,
3696                                                                           jmethodID methodID, const jvalue *args)
3697 {
3698         methodinfo *m;
3699         jshort      s;
3700
3701         m = (methodinfo *) methodID;
3702
3703         s = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3704
3705         return s;
3706 }
3707
3708
3709 jint _Jv_JNI_CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
3710                                                                  ...)
3711 {
3712         methodinfo *m;
3713         va_list     ap;
3714         jint        i;
3715
3716         m = (methodinfo *) methodID;
3717
3718         va_start(ap, methodID);
3719         i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3720         va_end(ap);
3721
3722         return i;
3723 }
3724
3725
3726 jint _Jv_JNI_CallStaticIntMethodV(JNIEnv *env, jclass clazz,
3727                                                                   jmethodID methodID, va_list args)
3728 {
3729         methodinfo *m;
3730         jint        i;
3731
3732         m = (methodinfo *) methodID;
3733
3734         i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3735
3736         return i;
3737 }
3738
3739
3740 jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz,
3741                                                                   jmethodID methodID, const jvalue *args)
3742 {
3743         methodinfo *m;
3744         jint        i;
3745
3746         m = (methodinfo *) methodID;
3747
3748         i = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
3749
3750         return i;
3751 }
3752
3753
3754 jlong _Jv_JNI_CallStaticLongMethod(JNIEnv *env, jclass clazz,
3755                                                                    jmethodID methodID, ...)
3756 {
3757         methodinfo *m;
3758         va_list     ap;
3759         jlong       l;
3760
3761         m = (methodinfo *) methodID;
3762
3763         va_start(ap, methodID);
3764         l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3765         va_end(ap);
3766
3767         return l;
3768 }
3769
3770
3771 jlong _Jv_JNI_CallStaticLongMethodV(JNIEnv *env, jclass clazz,
3772                                                                         jmethodID methodID, va_list args)
3773 {
3774         methodinfo *m;
3775         jlong       l;
3776         
3777         m = (methodinfo *) methodID;
3778
3779         l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3780
3781         return l;
3782 }
3783
3784
3785 jlong _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz,
3786                                                                         jmethodID methodID, const jvalue *args)
3787 {
3788         methodinfo *m;
3789         jlong       l;
3790
3791         m = (methodinfo *) methodID;
3792
3793         l = _Jv_jni_CallLongMethodA(NULL, NULL, m, args);
3794
3795         return l;
3796 }
3797
3798
3799
3800 jfloat _Jv_JNI_CallStaticFloatMethod(JNIEnv *env, jclass clazz,
3801                                                                          jmethodID methodID, ...)
3802 {
3803         methodinfo *m;
3804         va_list     ap;
3805         jfloat      f;
3806
3807         m = (methodinfo *) methodID;
3808
3809         va_start(ap, methodID);
3810         f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3811         va_end(ap);
3812
3813         return f;
3814 }
3815
3816
3817 jfloat _Jv_JNI_CallStaticFloatMethodV(JNIEnv *env, jclass clazz,
3818                                                                           jmethodID methodID, va_list args)
3819 {
3820         methodinfo *m;
3821         jfloat      f;
3822
3823         m = (methodinfo *) methodID;
3824
3825         f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3826
3827         return f;
3828 }
3829
3830
3831 jfloat _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz,
3832                                                                           jmethodID methodID, const jvalue *args)
3833 {
3834         methodinfo *m;
3835         jfloat      f;
3836
3837         m = (methodinfo *) methodID;
3838
3839         f = _Jv_jni_CallFloatMethodA(NULL, NULL, m, args);
3840
3841         return f;
3842 }
3843
3844
3845 jdouble _Jv_JNI_CallStaticDoubleMethod(JNIEnv *env, jclass clazz,
3846                                                                            jmethodID methodID, ...)
3847 {
3848         methodinfo *m;
3849         va_list     ap;
3850         jdouble     d;
3851
3852         m = (methodinfo *) methodID;
3853
3854         va_start(ap, methodID);
3855         d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3856         va_end(ap);
3857
3858         return d;
3859 }
3860
3861
3862 jdouble _Jv_JNI_CallStaticDoubleMethodV(JNIEnv *env, jclass clazz,
3863                                                                                 jmethodID methodID, va_list args)
3864 {
3865         methodinfo *m;
3866         jdouble     d;
3867
3868         m = (methodinfo *) methodID;
3869
3870         d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3871
3872         return d;
3873 }
3874
3875
3876 jdouble _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz,
3877                                                                                 jmethodID methodID, const jvalue *args)
3878 {
3879         methodinfo *m;
3880         jdouble     d;
3881
3882         m = (methodinfo *) methodID;
3883
3884         d = _Jv_jni_CallDoubleMethodA(NULL, NULL, m, args);
3885
3886         return d;
3887 }
3888
3889
3890 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
3891                                                                   jmethodID methodID, ...)
3892 {
3893         methodinfo *m;
3894         va_list     ap;
3895
3896         m = (methodinfo *) methodID;
3897
3898         va_start(ap, methodID);
3899         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3900         va_end(ap);
3901 }
3902
3903
3904 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
3905                                                                    jmethodID methodID, va_list args)
3906 {
3907         methodinfo *m;
3908
3909         m = (methodinfo *) methodID;
3910
3911         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3912 }
3913
3914
3915 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
3916                                                                    jmethodID methodID, const jvalue * args)
3917 {
3918         methodinfo *m;
3919
3920         m = (methodinfo *) methodID;
3921
3922         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3923 }
3924
3925
3926 /* Accessing Static Fields ****************************************************/
3927
3928 /* GetStaticFieldID ************************************************************
3929
3930    Returns the field ID for a static field of a class. The field is
3931    specified by its name and signature. The GetStatic<type>Field and
3932    SetStatic<type>Field families of accessor functions use field IDs
3933    to retrieve static fields.
3934
3935 *******************************************************************************/
3936
3937 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
3938                                                                   const char *sig)
3939 {
3940         classinfo *c;
3941         fieldinfo *f;
3942         utf       *uname;
3943         utf       *usig;
3944
3945         STATISTICS(jniinvokation());
3946
3947         c = (classinfo *) clazz;
3948
3949         uname = utf_new_char((char *) name);
3950         usig  = utf_new_char((char *) sig);
3951
3952         f = class_findfield(c, uname, usig);
3953         
3954         if (f == NULL)
3955                 exceptions_throw_nosuchfielderror(c, uname);
3956
3957         return (jfieldID) f;
3958 }
3959
3960
3961 /* GetStatic<type>Field ********************************************************
3962
3963    This family of accessor routines returns the value of a static
3964    field of an object.
3965
3966 *******************************************************************************/
3967
3968 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
3969                                                                          jfieldID fieldID)
3970 {
3971         classinfo *c;
3972         fieldinfo *f;
3973
3974         STATISTICS(jniinvokation());
3975
3976         c = (classinfo *) clazz;
3977         f = (fieldinfo *) fieldID;
3978
3979         if (!(c->state & CLASS_INITIALIZED))
3980                 if (!initialize_class(c))
3981                         return NULL;
3982
3983         return _Jv_JNI_NewLocalRef(env, f->value.a);
3984 }
3985
3986
3987 jboolean _Jv_JNI_GetStaticBooleanField(JNIEnv *env, jclass clazz,
3988                                                                            jfieldID fieldID)
3989 {
3990         classinfo *c;
3991         fieldinfo *f;
3992
3993         STATISTICS(jniinvokation());
3994
3995         c = (classinfo *) clazz;
3996         f = (fieldinfo *) fieldID;
3997
3998         if (!(c->state & CLASS_INITIALIZED))
3999                 if (!initialize_class(c))
4000                         return false;
4001
4002         return f->value.i;
4003 }
4004
4005
4006 jbyte _Jv_JNI_GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4007 {
4008         classinfo *c;
4009         fieldinfo *f;
4010
4011         STATISTICS(jniinvokation());
4012
4013         c = (classinfo *) clazz;
4014         f = (fieldinfo *) fieldID;
4015
4016         if (!(c->state & CLASS_INITIALIZED))
4017                 if (!initialize_class(c))
4018                         return 0;
4019
4020         return f->value.i;
4021 }
4022
4023
4024 jchar _Jv_JNI_GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4025 {
4026         classinfo *c;
4027         fieldinfo *f;
4028
4029         STATISTICS(jniinvokation());
4030
4031         c = (classinfo *) clazz;
4032         f = (fieldinfo *) fieldID;
4033
4034         if (!(c->state & CLASS_INITIALIZED))
4035                 if (!initialize_class(c))
4036                         return 0;
4037
4038         return f->value.i;
4039 }
4040
4041
4042 jshort _Jv_JNI_GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4043 {
4044         classinfo *c;
4045         fieldinfo *f;
4046
4047         STATISTICS(jniinvokation());
4048
4049         c = (classinfo *) clazz;
4050         f = (fieldinfo *) fieldID;
4051
4052         if (!(c->state & CLASS_INITIALIZED))
4053                 if (!initialize_class(c))
4054                         return 0;
4055
4056         return f->value.i;
4057 }
4058
4059
4060 jint _Jv_JNI_GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4061 {
4062         classinfo *c;
4063         fieldinfo *f;
4064
4065         STATISTICS(jniinvokation());
4066
4067         c = (classinfo *) clazz;
4068         f = (fieldinfo *) fieldID;
4069
4070         if (!(c->state & CLASS_INITIALIZED))
4071                 if (!initialize_class(c))
4072                         return 0;
4073
4074         return f->value.i;
4075 }
4076
4077
4078 jlong _Jv_JNI_GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4079 {
4080         classinfo *c;
4081         fieldinfo *f;
4082
4083         STATISTICS(jniinvokation());
4084
4085         c = (classinfo *) clazz;
4086         f = (fieldinfo *) fieldID;
4087
4088         if (!(c->state & CLASS_INITIALIZED))
4089                 if (!initialize_class(c))
4090                         return 0;
4091
4092         return f->value.l;
4093 }
4094
4095
4096 jfloat _Jv_JNI_GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
4097 {
4098         classinfo *c;
4099         fieldinfo *f;
4100
4101         STATISTICS(jniinvokation());
4102
4103         c = (classinfo *) clazz;
4104         f = (fieldinfo *) fieldID;
4105
4106         if (!(c->state & CLASS_INITIALIZED))
4107                 if (!initialize_class(c))
4108                         return 0.0;
4109
4110         return f->value.f;
4111 }
4112
4113
4114 jdouble _Jv_JNI_GetStaticDoubleField(JNIEnv *env, jclass clazz,
4115                                                                          jfieldID fieldID)
4116 {
4117         classinfo *c;
4118         fieldinfo *f;
4119
4120         STATISTICS(jniinvokation());
4121
4122         c = (classinfo *) clazz;
4123         f = (fieldinfo *) fieldID;
4124
4125         if (!(c->state & CLASS_INITIALIZED))
4126                 if (!initialize_class(c))
4127                         return 0.0;
4128
4129         return f->value.d;
4130 }
4131
4132
4133 /*  SetStatic<type>Field *******************************************************
4134
4135         This family of accessor routines sets the value of a static field
4136         of an object.
4137
4138 *******************************************************************************/
4139
4140 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4141                                                                   jobject value)
4142 {
4143         classinfo *c;
4144         fieldinfo *f;
4145
4146         STATISTICS(jniinvokation());
4147
4148         c = (classinfo *) clazz;
4149         f = (fieldinfo *) fieldID;
4150
4151         if (!(c->state & CLASS_INITIALIZED))
4152                 if (!initialize_class(c))
4153                         return;
4154
4155         f->value.a = value;
4156 }
4157
4158
4159 void _Jv_JNI_SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4160                                                                    jboolean value)
4161 {
4162         classinfo *c;
4163         fieldinfo *f;
4164
4165         STATISTICS(jniinvokation());
4166
4167         c = (classinfo *) clazz;
4168         f = (fieldinfo *) fieldID;
4169
4170         if (!(c->state & CLASS_INITIALIZED))
4171                 if (!initialize_class(c))
4172                         return;
4173
4174         f->value.i = value;
4175 }
4176
4177
4178 void _Jv_JNI_SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4179                                                                 jbyte value)
4180 {
4181         classinfo *c;
4182         fieldinfo *f;
4183
4184         STATISTICS(jniinvokation());
4185
4186         c = (classinfo *) clazz;
4187         f = (fieldinfo *) fieldID;
4188
4189         if (!(c->state & CLASS_INITIALIZED))
4190                 if (!initialize_class(c))
4191                         return;
4192
4193         f->value.i = value;
4194 }
4195
4196
4197 void _Jv_JNI_SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4198                                                                 jchar value)
4199 {
4200         classinfo *c;
4201         fieldinfo *f;
4202
4203         STATISTICS(jniinvokation());
4204
4205         c = (classinfo *) clazz;
4206         f = (fieldinfo *) fieldID;
4207
4208         if (!(c->state & CLASS_INITIALIZED))
4209                 if (!initialize_class(c))
4210                         return;
4211
4212         f->value.i = value;
4213 }
4214
4215
4216 void _Jv_JNI_SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4217                                                                  jshort value)
4218 {
4219         classinfo *c;
4220         fieldinfo *f;
4221
4222         STATISTICS(jniinvokation());
4223
4224         c = (classinfo *) clazz;
4225         f = (fieldinfo *) fieldID;
4226
4227         if (!(c->state & CLASS_INITIALIZED))
4228                 if (!initialize_class(c))
4229                         return;
4230
4231         f->value.i = value;
4232 }
4233
4234
4235 void _Jv_JNI_SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4236                                                            jint value)
4237 {
4238         classinfo *c;
4239         fieldinfo *f;
4240
4241         STATISTICS(jniinvokation());
4242
4243         c = (classinfo *) clazz;
4244         f = (fieldinfo *) fieldID;
4245
4246         if (!(c->state & CLASS_INITIALIZED))
4247                 if (!initialize_class(c))
4248                         return;
4249
4250         f->value.i = value;
4251 }
4252
4253
4254 void _Jv_JNI_SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4255                                                                 jlong value)
4256 {
4257         classinfo *c;
4258         fieldinfo *f;
4259
4260         STATISTICS(jniinvokation());
4261
4262         c = (classinfo *) clazz;
4263         f = (fieldinfo *) fieldID;
4264
4265         if (!(c->state & CLASS_INITIALIZED))
4266                 if (!initialize_class(c))
4267                         return;
4268
4269         f->value.l = value;
4270 }
4271
4272
4273 void _Jv_JNI_SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4274                                                                  jfloat value)
4275 {
4276         classinfo *c;
4277         fieldinfo *f;
4278
4279         STATISTICS(jniinvokation());
4280
4281         c = (classinfo *) clazz;
4282         f = (fieldinfo *) fieldID;
4283
4284         if (!(c->state & CLASS_INITIALIZED))
4285                 if (!initialize_class(c))
4286                         return;
4287
4288         f->value.f = value;
4289 }
4290
4291
4292 void _Jv_JNI_SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID,
4293                                                                   jdouble value)
4294 {
4295         classinfo *c;
4296         fieldinfo *f;
4297
4298         STATISTICS(jniinvokation());
4299
4300         c = (classinfo *) clazz;
4301         f = (fieldinfo *) fieldID;
4302
4303         if (!(c->state & CLASS_INITIALIZED))
4304                 if (!initialize_class(c))
4305                         return;
4306
4307         f->value.d = value;
4308 }
4309
4310
4311 /* String Operations **********************************************************/
4312
4313 /* NewString *******************************************************************
4314
4315    Create new java.lang.String object from an array of Unicode
4316    characters.
4317
4318 *******************************************************************************/
4319
4320 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
4321 {
4322         java_lang_String *s;
4323         java_chararray   *a;
4324         u4                i;
4325
4326         STATISTICS(jniinvokation());
4327         
4328         s = (java_lang_String *) builtin_new(class_java_lang_String);
4329         a = builtin_newarray_char(len);
4330
4331         /* javastring or characterarray could not be created */
4332         if ((a == NULL) || (s == NULL))
4333                 return NULL;
4334
4335         /* copy text */
4336         for (i = 0; i < len; i++)
4337                 a->data[i] = buf[i];
4338
4339         s->value  = a;
4340         s->offset = 0;
4341         s->count  = len;
4342
4343         return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4344 }
4345
4346
4347 static jchar emptyStringJ[]={0,0};
4348
4349 /* GetStringLength *************************************************************
4350
4351    Returns the length (the count of Unicode characters) of a Java
4352    string.
4353
4354 *******************************************************************************/
4355
4356 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
4357 {
4358         java_lang_String *s;
4359
4360         s = (java_lang_String *) str;
4361
4362         return s->count;
4363 }
4364
4365
4366 /********************  convertes javastring to u2-array ****************************/
4367         
4368 u2 *javastring_tou2(jstring so) 
4369 {
4370         java_lang_String *s;
4371         java_chararray   *a;
4372         u2               *stringbuffer;
4373         u4                i;
4374
4375         STATISTICS(jniinvokation());
4376         
4377         s = (java_lang_String *) so;
4378
4379         if (!s)
4380                 return NULL;
4381
4382         a = s->value;
4383
4384         if (!a)
4385                 return NULL;
4386
4387         /* allocate memory */
4388
4389         stringbuffer = MNEW(u2, s->count + 1);
4390
4391         /* copy text */
4392
4393         for (i = 0; i < s->count; i++)
4394                 stringbuffer[i] = a->data[s->offset + i];
4395         
4396         /* terminate string */
4397
4398         stringbuffer[i] = '\0';
4399
4400         return stringbuffer;
4401 }
4402
4403
4404 /* GetStringChars **************************************************************
4405
4406    Returns a pointer to the array of Unicode characters of the
4407    string. This pointer is valid until ReleaseStringChars() is called.
4408
4409 *******************************************************************************/
4410
4411 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
4412 {       
4413         jchar *jc;
4414
4415         STATISTICS(jniinvokation());
4416
4417         jc = javastring_tou2(str);
4418
4419         if (jc) {
4420                 if (isCopy)
4421                         *isCopy = JNI_TRUE;
4422
4423                 return jc;
4424         }
4425
4426         if (isCopy)
4427                 *isCopy = JNI_TRUE;
4428
4429         return emptyStringJ;
4430 }
4431
4432
4433 /* ReleaseStringChars **********************************************************
4434
4435    Informs the VM that the native code no longer needs access to
4436    chars. The chars argument is a pointer obtained from string using
4437    GetStringChars().
4438
4439 *******************************************************************************/
4440
4441 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
4442 {
4443         STATISTICS(jniinvokation());
4444
4445         if (chars == emptyStringJ)
4446                 return;
4447
4448         MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
4449 }
4450
4451
4452 /* NewStringUTF ****************************************************************
4453
4454    Constructs a new java.lang.String object from an array of UTF-8
4455    characters.
4456
4457 *******************************************************************************/
4458
4459 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
4460 {
4461         java_lang_String *s;
4462
4463         STATISTICS(jniinvokation());
4464
4465         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
4466
4467     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4468 }
4469
4470
4471 /****************** returns the utf8 length in bytes of a string *******************/
4472
4473 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
4474 {   
4475     java_lang_String *s;
4476         s4                length;
4477
4478         STATISTICS(jniinvokation());
4479
4480         s = (java_lang_String *) string;
4481
4482     length = u2_utflength(s->value->data, s->count);
4483
4484         return length;
4485 }
4486
4487
4488 /* GetStringUTFChars ***********************************************************
4489
4490    Returns a pointer to an array of UTF-8 characters of the
4491    string. This array is valid until it is released by
4492    ReleaseStringUTFChars().
4493
4494 *******************************************************************************/
4495
4496 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
4497                                                                           jboolean *isCopy)
4498 {
4499         utf *u;
4500
4501         STATISTICS(jniinvokation());
4502
4503         if (string == NULL)
4504                 return "";
4505
4506         if (isCopy)
4507                 *isCopy = JNI_TRUE;
4508         
4509         u = javastring_toutf((java_objectheader *) string, false);
4510
4511         if (u != NULL)
4512                 return u->text;
4513
4514         return "";
4515 }
4516
4517
4518 /* ReleaseStringUTFChars *******************************************************
4519
4520    Informs the VM that the native code no longer needs access to
4521    utf. The utf argument is a pointer derived from string using
4522    GetStringUTFChars().
4523
4524 *******************************************************************************/
4525
4526 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
4527 {
4528         STATISTICS(jniinvokation());
4529
4530     /* XXX we don't release utf chars right now, perhaps that should be done 
4531            later. Since there is always one reference the garbage collector will
4532            never get them */
4533 }
4534
4535
4536 /* Array Operations ***********************************************************/
4537
4538 /* GetArrayLength **************************************************************
4539
4540    Returns the number of elements in the array.
4541
4542 *******************************************************************************/
4543
4544 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
4545 {
4546         java_arrayheader *a;
4547
4548         STATISTICS(jniinvokation());
4549
4550         a = (java_arrayheader *) array;
4551
4552         return a->size;
4553 }
4554
4555
4556 /* NewObjectArray **************************************************************
4557
4558    Constructs a new array holding objects in class elementClass. All
4559    elements are initially set to initialElement.
4560
4561 *******************************************************************************/
4562
4563 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
4564                                                                         jclass elementClass, jobject initialElement)
4565 {
4566         classinfo         *c;
4567         java_objectheader *o;
4568         java_objectarray  *oa;
4569         s4                 i;
4570
4571         STATISTICS(jniinvokation());
4572
4573         c = (classinfo *) elementClass;
4574         o = (java_objectheader *) initialElement;
4575
4576         if (length < 0) {
4577                 exceptions_throw_negativearraysizeexception();
4578                 return NULL;
4579         }
4580
4581     oa = builtin_anewarray(length, c);
4582
4583         if (oa == NULL)
4584                 return NULL;
4585
4586         /* set all elements to initialElement */
4587
4588         for (i = 0; i < length; i++)
4589                 oa->data[i] = o;
4590
4591         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
4592 }
4593
4594
4595 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
4596                                                                           jsize index)
4597 {
4598         java_objectarray  *oa;
4599         java_objectheader *o;
4600
4601         STATISTICS(jniinvokation());
4602
4603         oa = (java_objectarray *) array;
4604
4605         if (index >= oa->header.size) {
4606                 exceptions_throw_arrayindexoutofboundsexception();
4607                 return NULL;
4608         }
4609
4610         o = oa->data[index];
4611
4612         return _Jv_JNI_NewLocalRef(env, (jobject) o);
4613 }
4614
4615
4616 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
4617                                                                    jsize index, jobject val)
4618 {
4619         java_objectarray  *oa;
4620         java_objectheader *o;
4621
4622         STATISTICS(jniinvokation());
4623
4624         oa = (java_objectarray *) array;
4625         o  = (java_objectheader *) val;
4626
4627         if (index >= oa->header.size) {
4628                 exceptions_throw_arrayindexoutofboundsexception();
4629                 return;
4630         }
4631
4632         /* check if the class of value is a subclass of the element class
4633            of the array */
4634
4635         if (!builtin_canstore(oa, o))
4636                 return;
4637
4638         oa->data[index] = o;
4639 }
4640
4641
4642 jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
4643 {
4644         java_booleanarray *ba;
4645
4646         STATISTICS(jniinvokation());
4647
4648         if (len < 0) {
4649                 exceptions_throw_negativearraysizeexception();
4650                 return NULL;
4651         }
4652
4653         ba = builtin_newarray_boolean(len);
4654
4655         return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4656 }
4657
4658
4659 jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
4660 {
4661         java_bytearray *ba;
4662
4663         STATISTICS(jniinvokation());
4664
4665         if (len < 0) {
4666                 exceptions_throw_negativearraysizeexception();
4667                 return NULL;
4668         }
4669
4670         ba = builtin_newarray_byte(len);
4671
4672         return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4673 }
4674
4675
4676 jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
4677 {
4678         java_chararray *ca;
4679
4680         STATISTICS(jniinvokation());
4681
4682         if (len < 0) {
4683                 exceptions_throw_negativearraysizeexception();
4684                 return NULL;
4685         }
4686
4687         ca = builtin_newarray_char(len);
4688
4689         return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
4690 }
4691
4692
4693 jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
4694 {
4695         java_shortarray *sa;
4696
4697         STATISTICS(jniinvokation());
4698
4699         if (len < 0) {
4700                 exceptions_throw_negativearraysizeexception();
4701                 return NULL;
4702         }
4703
4704         sa = builtin_newarray_short(len);
4705
4706         return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
4707 }
4708
4709
4710 jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
4711 {
4712         java_intarray *ia;
4713
4714         STATISTICS(jniinvokation());
4715
4716         if (len < 0) {
4717                 exceptions_throw_negativearraysizeexception();
4718                 return NULL;
4719         }
4720
4721         ia = builtin_newarray_int(len);
4722
4723         return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
4724 }
4725
4726
4727 jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
4728 {
4729         java_longarray *la;
4730
4731         STATISTICS(jniinvokation());
4732
4733         if (len < 0) {
4734                 exceptions_throw_negativearraysizeexception();
4735                 return NULL;
4736         }
4737
4738         la = builtin_newarray_long(len);
4739
4740         return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
4741 }
4742
4743
4744 jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
4745 {
4746         java_floatarray *fa;
4747
4748         STATISTICS(jniinvokation());
4749
4750         if (len < 0) {
4751                 exceptions_throw_negativearraysizeexception();
4752                 return NULL;
4753         }
4754
4755         fa = builtin_newarray_float(len);
4756
4757         return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
4758 }
4759
4760
4761 jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
4762 {
4763         java_doublearray *da;
4764
4765         STATISTICS(jniinvokation());
4766
4767         if (len < 0) {
4768                 exceptions_throw_negativearraysizeexception();
4769                 return NULL;
4770         }
4771
4772         da = builtin_newarray_double(len);
4773
4774         return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
4775 }
4776
4777
4778 /* Get<PrimitiveType>ArrayElements *********************************************
4779
4780    A family of functions that returns the body of the primitive array.
4781
4782 *******************************************************************************/
4783
4784 jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4785                                                                                   jboolean *isCopy)
4786 {
4787         java_booleanarray *ba;
4788
4789         STATISTICS(jniinvokation());
4790
4791         ba = (java_booleanarray *) array;
4792
4793         if (isCopy)
4794                 *isCopy = JNI_FALSE;
4795
4796         return ba->data;
4797 }
4798
4799
4800 jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
4801                                                                         jboolean *isCopy)
4802 {
4803         java_bytearray *ba;
4804
4805         STATISTICS(jniinvokation());
4806
4807         ba = (java_bytearray *) array;
4808
4809         if (isCopy)
4810                 *isCopy = JNI_FALSE;
4811
4812         return ba->data;
4813 }
4814
4815
4816 jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
4817                                                                         jboolean *isCopy)
4818 {
4819         java_chararray *ca;
4820
4821         STATISTICS(jniinvokation());
4822
4823         ca = (java_chararray *) array;
4824
4825         if (isCopy)
4826                 *isCopy = JNI_FALSE;
4827
4828         return ca->data;
4829 }
4830
4831
4832 jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
4833                                                                           jboolean *isCopy)
4834 {
4835         java_shortarray *sa;
4836
4837         STATISTICS(jniinvokation());
4838
4839         sa = (java_shortarray *) array;
4840
4841         if (isCopy)
4842                 *isCopy = JNI_FALSE;
4843
4844         return sa->data;
4845 }
4846
4847
4848 jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
4849                                                                   jboolean *isCopy)
4850 {
4851         java_intarray *ia;
4852
4853         STATISTICS(jniinvokation());
4854
4855         ia = (java_intarray *) array;
4856
4857         if (isCopy)
4858                 *isCopy = JNI_FALSE;
4859
4860         return ia->data;
4861 }
4862
4863
4864 jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
4865                                                                         jboolean *isCopy)
4866 {
4867         java_longarray *la;
4868
4869         STATISTICS(jniinvokation());
4870
4871         la = (java_longarray *) array;
4872
4873         if (isCopy)
4874                 *isCopy = JNI_FALSE;
4875
4876         /* We cast this one to prevent a compiler warning on 64-bit
4877            systems since GNU Classpath typedef jlong to long long. */
4878
4879         return (jlong *) la->data;
4880 }
4881
4882
4883 jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
4884                                                                           jboolean *isCopy)
4885 {
4886         java_floatarray *fa;
4887
4888         STATISTICS(jniinvokation());
4889
4890         fa = (java_floatarray *) array;
4891
4892         if (isCopy)
4893                 *isCopy = JNI_FALSE;
4894
4895         return fa->data;
4896 }
4897
4898
4899 jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4900                                                                                 jboolean *isCopy)
4901 {
4902         java_doublearray *da;
4903
4904         STATISTICS(jniinvokation());
4905
4906         da = (java_doublearray *) array;
4907
4908         if (isCopy)
4909                 *isCopy = JNI_FALSE;
4910
4911         return da->data;
4912 }
4913
4914
4915 /* Release<PrimitiveType>ArrayElements *****************************************
4916
4917    A family of functions that informs the VM that the native code no
4918    longer needs access to elems. The elems argument is a pointer
4919    derived from array using the corresponding
4920    Get<PrimitiveType>ArrayElements() function. If necessary, this
4921    function copies back all changes made to elems to the original
4922    array.
4923
4924 *******************************************************************************/
4925
4926 void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4927                                                                                  jboolean *elems, jint mode)
4928 {
4929         java_booleanarray *ba;
4930
4931         STATISTICS(jniinvokation());
4932
4933         ba = (java_booleanarray *) array;
4934
4935         if (elems != ba->data) {
4936                 switch (mode) {
4937                 case JNI_COMMIT:
4938                         MCOPY(ba->data, elems, u1, ba->header.size);
4939                         break;
4940                 case 0:
4941                         MCOPY(ba->data, elems, u1, ba->header.size);
4942                         /* XXX TWISTI how should it be freed? */
4943                         break;
4944                 case JNI_ABORT:
4945                         /* XXX TWISTI how should it be freed? */
4946                         break;
4947                 }
4948         }
4949 }
4950
4951
4952 void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
4953                                                                           jbyte *elems, jint mode)
4954 {
4955         java_bytearray *ba;
4956
4957         STATISTICS(jniinvokation());
4958
4959         ba = (java_bytearray *) array;
4960
4961         if (elems != ba->data) {
4962                 switch (mode) {
4963                 case JNI_COMMIT:
4964                         MCOPY(ba->data, elems, s1, ba->header.size);
4965                         break;
4966                 case 0:
4967                         MCOPY(ba->data, elems, s1, ba->header.size);
4968                         /* XXX TWISTI how should it be freed? */
4969                         break;
4970                 case JNI_ABORT:
4971                         /* XXX TWISTI how should it be freed? */
4972                         break;
4973                 }
4974         }
4975 }
4976
4977
4978 void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
4979                                                                           jchar *elems, jint mode)
4980 {
4981         java_chararray *ca;
4982
4983         STATISTICS(jniinvokation());
4984
4985         ca = (java_chararray *) array;
4986
4987         if (elems != ca->data) {
4988                 switch (mode) {
4989                 case JNI_COMMIT:
4990                         MCOPY(ca->data, elems, u2, ca->header.size);
4991                         break;
4992                 case 0:
4993                         MCOPY(ca->data, elems, u2, ca->header.size);
4994                         /* XXX TWISTI how should it be freed? */
4995                         break;
4996                 case JNI_ABORT:
4997                         /* XXX TWISTI how should it be freed? */
4998                         break;
4999                 }
5000         }
5001 }
5002
5003
5004 void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
5005                                                                            jshort *elems, jint mode)
5006 {
5007         java_shortarray *sa;
5008
5009         STATISTICS(jniinvokation());
5010
5011         sa = (java_shortarray *) array;
5012
5013         if (elems != sa->data) {
5014                 switch (mode) {
5015                 case JNI_COMMIT:
5016                         MCOPY(sa->data, elems, s2, sa->header.size);
5017                         break;
5018                 case 0:
5019                         MCOPY(sa->data, elems, s2, sa->header.size);
5020                         /* XXX TWISTI how should it be freed? */
5021                         break;
5022                 case JNI_ABORT:
5023                         /* XXX TWISTI how should it be freed? */
5024                         break;
5025                 }
5026         }
5027 }
5028
5029
5030 void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
5031                                                                          jint mode)
5032 {
5033         java_intarray *ia;
5034
5035         STATISTICS(jniinvokation());
5036
5037         ia = (java_intarray *) array;
5038
5039         if (elems != ia->data) {
5040                 switch (mode) {
5041                 case JNI_COMMIT:
5042                         MCOPY(ia->data, elems, s4, ia->header.size);
5043                         break;
5044                 case 0:
5045                         MCOPY(ia->data, elems, s4, ia->header.size);
5046                         /* XXX TWISTI how should it be freed? */
5047                         break;
5048                 case JNI_ABORT:
5049                         /* XXX TWISTI how should it be freed? */
5050                         break;
5051                 }
5052         }
5053 }
5054
5055
5056 void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
5057                                                                           jlong *elems, jint mode)
5058 {
5059         java_longarray *la;
5060
5061         STATISTICS(jniinvokation());
5062
5063         la = (java_longarray *) array;
5064
5065         /* We cast this one to prevent a compiler warning on 64-bit
5066            systems since GNU Classpath typedef jlong to long long. */
5067
5068         if ((s8 *) elems != la->data) {
5069                 switch (mode) {
5070                 case JNI_COMMIT:
5071                         MCOPY(la->data, elems, s8, la->header.size);
5072                         break;
5073                 case 0:
5074                         MCOPY(la->data, elems, s8, la->header.size);
5075                         /* XXX TWISTI how should it be freed? */
5076                         break;
5077                 case JNI_ABORT:
5078                         /* XXX TWISTI how should it be freed? */
5079                         break;
5080                 }
5081         }
5082 }
5083
5084
5085 void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
5086                                                                            jfloat *elems, jint mode)
5087 {
5088         java_floatarray *fa;
5089
5090         STATISTICS(jniinvokation());
5091
5092         fa = (java_floatarray *) array;
5093
5094         if (elems != fa->data) {
5095                 switch (mode) {
5096                 case JNI_COMMIT:
5097                         MCOPY(fa->data, elems, float, fa->header.size);
5098                         break;
5099                 case 0:
5100                         MCOPY(fa->data, elems, float, fa->header.size);
5101                         /* XXX TWISTI how should it be freed? */
5102                         break;
5103                 case JNI_ABORT:
5104                         /* XXX TWISTI how should it be freed? */
5105                         break;
5106                 }
5107         }
5108 }
5109
5110
5111 void _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
5112                                                                                 jdouble *elems, jint mode)
5113 {
5114         java_doublearray *da;
5115
5116         STATISTICS(jniinvokation());
5117
5118         da = (java_doublearray *) array;
5119
5120         if (elems != da->data) {
5121                 switch (mode) {
5122                 case JNI_COMMIT:
5123                         MCOPY(da->data, elems, double, da->header.size);
5124                         break;
5125                 case 0:
5126                         MCOPY(da->data, elems, double, da->header.size);
5127                         /* XXX TWISTI how should it be freed? */
5128                         break;
5129                 case JNI_ABORT:
5130                         /* XXX TWISTI how should it be freed? */
5131                         break;
5132                 }
5133         }
5134 }
5135
5136
5137 /*  Get<PrimitiveType>ArrayRegion **********************************************
5138
5139         A family of functions that copies a region of a primitive array
5140         into a buffer.
5141
5142 *******************************************************************************/
5143
5144 void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5145                                                                    jsize start, jsize len, jboolean *buf)
5146 {
5147         java_booleanarray *ba;
5148
5149         STATISTICS(jniinvokation());
5150
5151         ba = (java_booleanarray *) array;
5152
5153     if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5154                 exceptions_throw_arrayindexoutofboundsexception();
5155     else
5156                 MCOPY(buf, &ba->data[start], u1, len);
5157 }
5158
5159
5160 void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5161                                                                 jsize len, jbyte *buf)
5162 {
5163         java_bytearray *ba;
5164
5165         STATISTICS(jniinvokation());
5166
5167         ba = (java_bytearray *) array;
5168
5169         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5170                 exceptions_throw_arrayindexoutofboundsexception();
5171         else
5172                 MCOPY(buf, &ba->data[start], s1, len);
5173 }
5174
5175
5176 void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5177                                                                 jsize len, jchar *buf)
5178 {
5179         java_chararray *ca;
5180
5181         STATISTICS(jniinvokation());
5182
5183         ca = (java_chararray *) array;
5184
5185         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5186                 exceptions_throw_arrayindexoutofboundsexception();
5187         else
5188                 MCOPY(buf, &ca->data[start], u2, len);
5189 }
5190
5191
5192 void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5193                                                                  jsize len, jshort *buf)
5194 {
5195         java_shortarray *sa;
5196
5197         STATISTICS(jniinvokation());
5198
5199         sa = (java_shortarray *) array;
5200
5201         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5202                 exceptions_throw_arrayindexoutofboundsexception();
5203         else    
5204                 MCOPY(buf, &sa->data[start], s2, len);
5205 }
5206
5207
5208 void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5209                                                            jsize len, jint *buf)
5210 {
5211         java_intarray *ia;
5212
5213         STATISTICS(jniinvokation());
5214
5215         ia = (java_intarray *) array;
5216
5217         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5218                 exceptions_throw_arrayindexoutofboundsexception();
5219         else
5220                 MCOPY(buf, &ia->data[start], s4, len);
5221 }
5222
5223
5224 void _Jv_JNI_GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start,
5225                                                                 jsize len, jlong *buf)
5226 {
5227         java_longarray *la;
5228
5229         STATISTICS(jniinvokation());
5230
5231         la = (java_longarray *) array;
5232
5233         if ((start < 0) || (len < 0) || (start + len > la->header.size))
5234                 exceptions_throw_arrayindexoutofboundsexception();
5235         else
5236                 MCOPY(buf, &la->data[start], s8, len);
5237 }
5238
5239
5240 void _Jv_JNI_GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5241                                                                  jsize len, jfloat *buf)
5242 {
5243         java_floatarray *fa;
5244
5245         STATISTICS(jniinvokation());
5246
5247         fa = (java_floatarray *) array;
5248
5249         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5250                 exceptions_throw_arrayindexoutofboundsexception();
5251         else
5252                 MCOPY(buf, &fa->data[start], float, len);
5253 }
5254
5255
5256 void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5257                                                                   jsize len, jdouble *buf)
5258 {
5259         java_doublearray *da;
5260
5261         STATISTICS(jniinvokation());
5262
5263         da = (java_doublearray *) array;
5264
5265         if ((start < 0) || (len < 0) || (start + len > da->header.size))
5266                 exceptions_throw_arrayindexoutofboundsexception();
5267         else
5268                 MCOPY(buf, &da->data[start], double, len);
5269 }
5270
5271
5272 /*  Set<PrimitiveType>ArrayRegion **********************************************
5273
5274         A family of functions that copies back a region of a primitive
5275         array from a buffer.
5276
5277 *******************************************************************************/
5278
5279 void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
5280                                                                    jsize start, jsize len, const jboolean *buf)
5281 {
5282         java_booleanarray *ba;
5283
5284         STATISTICS(jniinvokation());
5285
5286         ba = (java_booleanarray *) array;
5287
5288         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5289                 exceptions_throw_arrayindexoutofboundsexception();
5290         else
5291                 MCOPY(&ba->data[start], buf, u1, len);
5292 }
5293
5294
5295 void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5296                                                                 jsize len, const jbyte *buf)
5297 {
5298         java_bytearray *ba;
5299
5300         STATISTICS(jniinvokation());
5301
5302         ba = (java_bytearray *) array;
5303
5304         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5305                 exceptions_throw_arrayindexoutofboundsexception();
5306         else
5307                 MCOPY(&ba->data[start], buf, s1, len);
5308 }
5309
5310
5311 void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5312                                                                 jsize len, const jchar *buf)
5313 {
5314         java_chararray *ca;
5315
5316         STATISTICS(jniinvokation());
5317
5318         ca = (java_chararray *) array;
5319
5320         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5321                 exceptions_throw_arrayindexoutofboundsexception();
5322         else
5323                 MCOPY(&ca->data[start], buf, u2, len);
5324 }
5325
5326
5327 void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5328                                                                  jsize len, const jshort *buf)
5329 {
5330         java_shortarray *sa;
5331
5332         STATISTICS(jniinvokation());
5333
5334         sa = (java_shortarray *) array;
5335
5336         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5337                 exceptions_throw_arrayindexoutofboundsexception();
5338         else
5339                 MCOPY(&sa->data[start], buf, s2, len);
5340 }
5341
5342
5343 void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5344                                                            jsize len, const jint *buf)
5345 {
5346         java_intarray *ia;
5347
5348         STATISTICS(jniinvokation());
5349
5350         ia = (java_intarray *) array;
5351
5352         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5353                 exceptions_throw_arrayindexoutofboundsexception();
5354         else
5355                 MCOPY(&ia->data[start], buf, s4, len);
5356 }
5357
5358
5359 void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
5360                                                                 jsize len, const jlong *buf)
5361 {
5362         java_longarray *la;
5363
5364         STATISTICS(jniinvokation());
5365
5366         la = (java_longarray *) array;
5367
5368         if ((start < 0) || (len < 0) || (start + len > la->header.size))
5369                 exceptions_throw_arrayindexoutofboundsexception();
5370         else
5371                 MCOPY(&la->data[start], buf, s8, len);
5372 }
5373
5374
5375 void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5376                                                                  jsize len, const jfloat *buf)
5377 {
5378         java_floatarray *fa;
5379
5380         STATISTICS(jniinvokation());
5381
5382         fa = (java_floatarray *) array;
5383
5384         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5385                 exceptions_throw_arrayindexoutofboundsexception();
5386         else
5387                 MCOPY(&fa->data[start], buf, float, len);
5388 }
5389
5390
5391 void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5392                                                                   jsize len, const jdouble *buf)
5393 {
5394         java_doublearray *da;
5395
5396         STATISTICS(jniinvokation());
5397
5398         da = (java_doublearray *) array;
5399
5400         if ((start < 0) || (len < 0) || (start + len > da->header.size))
5401                 exceptions_throw_arrayindexoutofboundsexception();
5402         else
5403                 MCOPY(&da->data[start], buf, double, len);
5404 }
5405
5406
5407 /* Registering Native Methods *************************************************/
5408
5409 /* RegisterNatives *************************************************************
5410
5411    Registers native methods with the class specified by the clazz
5412    argument. The methods parameter specifies an array of
5413    JNINativeMethod structures that contain the names, signatures, and
5414    function pointers of the native methods. The nMethods parameter
5415    specifies the number of native methods in the array.
5416
5417 *******************************************************************************/
5418
5419 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
5420                                                          const JNINativeMethod *methods, jint nMethods)
5421 {
5422         classinfo *c;
5423
5424         STATISTICS(jniinvokation());
5425
5426         c = (classinfo *) clazz;
5427
5428         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
5429         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
5430         */
5431
5432         native_method_register(c->name, methods, nMethods);
5433
5434     return 0;
5435 }
5436
5437
5438 /* UnregisterNatives ***********************************************************
5439
5440    Unregisters native methods of a class. The class goes back to the
5441    state before it was linked or registered with its native method
5442    functions.
5443
5444    This function should not be used in normal native code. Instead, it
5445    provides special programs a way to reload and relink native
5446    libraries.
5447
5448 *******************************************************************************/
5449
5450 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
5451 {
5452         STATISTICS(jniinvokation());
5453
5454         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
5455
5456     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
5457
5458     return 0;
5459 }
5460
5461
5462 /* Monitor Operations *********************************************************/
5463
5464 /* MonitorEnter ****************************************************************
5465
5466    Enters the monitor associated with the underlying Java object
5467    referred to by obj.
5468
5469 *******************************************************************************/
5470
5471 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
5472 {
5473         STATISTICS(jniinvokation());
5474
5475         if (obj == NULL) {
5476                 exceptions_throw_nullpointerexception();
5477                 return JNI_ERR;
5478         }
5479
5480         LOCK_MONITOR_ENTER(obj);
5481
5482         return JNI_OK;
5483 }
5484
5485
5486 /* MonitorExit *****************************************************************
5487
5488    The current thread must be the owner of the monitor associated with
5489    the underlying Java object referred to by obj. The thread
5490    decrements the counter indicating the number of times it has
5491    entered this monitor. If the value of the counter becomes zero, the
5492    current thread releases the monitor.
5493
5494 *******************************************************************************/
5495
5496 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
5497 {
5498         STATISTICS(jniinvokation());
5499
5500         if (obj == NULL) {
5501                 exceptions_throw_nullpointerexception();
5502                 return JNI_ERR;
5503         }
5504
5505         LOCK_MONITOR_EXIT(obj);
5506
5507         return JNI_OK;
5508 }
5509
5510
5511 /* JavaVM Interface ***********************************************************/
5512
5513 /* GetJavaVM *******************************************************************
5514
5515    Returns the Java VM interface (used in the Invocation API)
5516    associated with the current thread. The result is placed at the
5517    location pointed to by the second argument, vm.
5518
5519 *******************************************************************************/
5520
5521 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
5522 {
5523         STATISTICS(jniinvokation());
5524
5525     *vm = (JavaVM *) _Jv_jvm;
5526
5527         return 0;
5528 }
5529
5530
5531 /* GetStringRegion *************************************************************
5532
5533    Copies len number of Unicode characters beginning at offset start
5534    to the given buffer buf.
5535
5536    Throws StringIndexOutOfBoundsException on index overflow.
5537
5538 *******************************************************************************/
5539
5540 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
5541                                                          jchar *buf)
5542 {
5543         java_lang_String *s;
5544         java_chararray   *ca;
5545
5546         STATISTICS(jniinvokation());
5547
5548         s  = (java_lang_String *) str;
5549         ca = s->value;
5550
5551         if ((start < 0) || (len < 0) || (start > s->count) ||
5552                 (start + len > s->count)) {
5553                 exceptions_throw_stringindexoutofboundsexception();
5554                 return;
5555         }
5556
5557         MCOPY(buf, &ca->data[start], u2, len);
5558 }
5559
5560
5561 /* GetStringUTFRegion **********************************************************
5562
5563     Translates len number of Unicode characters beginning at offset
5564     start into UTF-8 format and place the result in the given buffer
5565     buf.
5566
5567     Throws StringIndexOutOfBoundsException on index overflow. 
5568
5569 *******************************************************************************/
5570
5571 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
5572                                                                 jsize len, char *buf)
5573 {
5574         java_lang_String *s;
5575         java_chararray   *ca;
5576         s4                i;
5577
5578         STATISTICS(jniinvokation());
5579
5580         s  = (java_lang_String *) str;
5581         ca = s->value;
5582
5583         if ((start < 0) || (len < 0) || (start > s->count) ||
5584                 (start + len > s->count)) {
5585                 exceptions_throw_stringindexoutofboundsexception();
5586                 return;
5587         }
5588
5589         /* XXX not sure if this is correct */
5590
5591         for (i = 0; i < len; i++)
5592                 buf[i] = ca->data[start + i];
5593
5594         buf[i] = '\0';
5595 }
5596
5597
5598 /* GetPrimitiveArrayCritical ***************************************************
5599
5600    Obtain a direct pointer to array elements.
5601
5602 *******************************************************************************/
5603
5604 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
5605                                                                                 jboolean *isCopy)
5606 {
5607         java_bytearray *ba;
5608         jbyte          *bp;
5609
5610         ba = (java_bytearray *) array;
5611
5612         /* do the same as Kaffe does */
5613
5614         bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
5615
5616         return (void *) bp;
5617 }
5618
5619
5620 /* ReleasePrimitiveArrayCritical ***********************************************
5621
5622    No specific documentation.
5623
5624 *******************************************************************************/
5625
5626 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
5627                                                                                    void *carray, jint mode)
5628 {
5629         STATISTICS(jniinvokation());
5630
5631         /* do the same as Kaffe does */
5632
5633         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
5634                                                                          mode);
5635 }
5636
5637
5638 /* GetStringCritical ***********************************************************
5639
5640    The semantics of these two functions are similar to the existing
5641    Get/ReleaseStringChars functions.
5642
5643 *******************************************************************************/
5644
5645 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
5646                                                                            jboolean *isCopy)
5647 {
5648         STATISTICS(jniinvokation());
5649
5650         return _Jv_JNI_GetStringChars(env, string, isCopy);
5651 }
5652
5653
5654 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
5655                                                                    const jchar *cstring)
5656 {
5657         STATISTICS(jniinvokation());
5658
5659         _Jv_JNI_ReleaseStringChars(env, string, cstring);
5660 }
5661
5662
5663 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
5664 {
5665         STATISTICS(jniinvokation());
5666
5667         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
5668
5669         return obj;
5670 }
5671
5672
5673 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
5674 {
5675         STATISTICS(jniinvokation());
5676
5677         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
5678 }
5679
5680
5681 /* NewGlobalRef ****************************************************************
5682
5683    Creates a new global reference to the object referred to by the obj
5684    argument.
5685
5686 *******************************************************************************/
5687     
5688 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
5689 {
5690         hashtable_global_ref_entry *gre;
5691         u4   key;                           /* hashkey                            */
5692         u4   slot;                          /* slot in hashtable                  */
5693         java_objectheader *o;
5694
5695         STATISTICS(jniinvokation());
5696
5697         o = (java_objectheader *) obj;
5698
5699         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5700
5701         /* normally addresses are aligned to 4, 8 or 16 bytes */
5702
5703         key  = ((u4) (ptrint) obj) >> 4;           /* align to 16-byte boundaries */
5704         slot = key & (hashtable_global_ref->size - 1);
5705         gre  = hashtable_global_ref->ptr[slot];
5706         
5707         /* search external hash chain for the entry */
5708
5709         while (gre) {
5710                 if (gre->o == o) {
5711                         /* global object found, increment the reference */
5712
5713                         gre->refs++;
5714
5715                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5716
5717                         return obj;
5718                 }
5719
5720                 gre = gre->hashlink;                /* next element in external chain */
5721         }
5722
5723         /* global ref not found, create a new one */
5724
5725         gre = NEW(hashtable_global_ref_entry);
5726
5727 #if defined(ENABLE_GC_CACAO)
5728         /* register global ref with the GC */
5729
5730         gc_reference_register(&(gre->o));
5731 #endif
5732
5733         gre->o    = o;
5734         gre->refs = 1;
5735
5736         /* insert entry into hashtable */
5737
5738         gre->hashlink = hashtable_global_ref->ptr[slot];
5739
5740         hashtable_global_ref->ptr[slot] = gre;
5741
5742         /* update number of hashtable-entries */
5743
5744         hashtable_global_ref->entries++;
5745
5746         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5747
5748         return obj;
5749 }
5750
5751
5752 /* DeleteGlobalRef *************************************************************
5753
5754    Deletes the global reference pointed to by globalRef.
5755
5756 *******************************************************************************/
5757
5758 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5759 {
5760         hashtable_global_ref_entry *gre;
5761         hashtable_global_ref_entry *prevgre;
5762         u4   key;                           /* hashkey                            */
5763         u4   slot;                          /* slot in hashtable                  */
5764         java_objectheader          *o;
5765
5766         STATISTICS(jniinvokation());
5767
5768         o = (java_objectheader *) globalRef;
5769
5770         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5771
5772         /* normally addresses are aligned to 4, 8 or 16 bytes */
5773
5774         key  = ((u4) (ptrint) globalRef) >> 4;     /* align to 16-byte boundaries */
5775         slot = key & (hashtable_global_ref->size - 1);
5776         gre  = hashtable_global_ref->ptr[slot];
5777
5778         /* initialize prevgre */
5779
5780         prevgre = NULL;
5781
5782         /* search external hash chain for the entry */
5783
5784         while (gre) {
5785                 if (gre->o == o) {
5786                         /* global object found, decrement the reference count */
5787
5788                         gre->refs--;
5789
5790                         /* if reference count is 0, remove the entry */
5791
5792                         if (gre->refs == 0) {
5793                                 /* special handling if it's the first in the chain */
5794
5795                                 if (prevgre == NULL)
5796                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
5797                                 else
5798                                         prevgre->hashlink = gre->hashlink;
5799
5800 #if defined(ENABLE_GC_CACAO)
5801                                 /* unregister global ref with the GC */
5802
5803                                 gc_reference_unregister(&(gre->o));
5804 #endif
5805
5806                                 FREE(gre, hashtable_global_ref_entry);
5807                         }
5808
5809                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5810
5811                         return;
5812                 }
5813
5814                 prevgre = gre;                    /* save current pointer for removal */
5815                 gre     = gre->hashlink;            /* next element in external chain */
5816         }
5817
5818         log_println("JNI-DeleteGlobalRef: global reference not found");
5819
5820         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5821 }
5822
5823
5824 /* ExceptionCheck **************************************************************
5825
5826    Returns JNI_TRUE when there is a pending exception; otherwise,
5827    returns JNI_FALSE.
5828
5829 *******************************************************************************/
5830
5831 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
5832 {
5833         java_objectheader *o;
5834
5835         STATISTICS(jniinvokation());
5836
5837         o = exceptions_get_exception();
5838
5839         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
5840 }
5841
5842
5843 /* New JNI 1.4 functions ******************************************************/
5844
5845 /* NewDirectByteBuffer *********************************************************
5846
5847    Allocates and returns a direct java.nio.ByteBuffer referring to the
5848    block of memory starting at the memory address address and
5849    extending capacity bytes.
5850
5851 *******************************************************************************/
5852
5853 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5854 {
5855 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5856         java_objectheader       *nbuf;
5857
5858 # if SIZEOF_VOID_P == 8
5859         gnu_classpath_Pointer64 *paddress;
5860 # else
5861         gnu_classpath_Pointer32 *paddress;
5862 # endif
5863
5864         STATISTICS(jniinvokation());
5865
5866         /* alocate a gnu.classpath.Pointer{32,64} object */
5867
5868 # if SIZEOF_VOID_P == 8
5869         if (!(paddress = (gnu_classpath_Pointer64 *)
5870                   builtin_new(class_gnu_classpath_Pointer64)))
5871 # else
5872         if (!(paddress = (gnu_classpath_Pointer32 *)
5873                   builtin_new(class_gnu_classpath_Pointer32)))
5874 # endif
5875                 return NULL;
5876
5877         /* fill gnu.classpath.Pointer{32,64} with address */
5878
5879         paddress->data = (ptrint) address;
5880
5881         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5882
5883         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5884                                                          (jmethodID) dbbirw_init, NULL, paddress,
5885                                                          (jint) capacity, (jint) capacity, (jint) 0);
5886
5887         /* add local reference and return the value */
5888
5889         return _Jv_JNI_NewLocalRef(env, nbuf);
5890 #else
5891         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
5892
5893         /* keep compiler happy */
5894
5895         return NULL;
5896 #endif
5897 }
5898
5899
5900 /* GetDirectBufferAddress ******************************************************
5901
5902    Fetches and returns the starting address of the memory region
5903    referenced by the given direct java.nio.Buffer.
5904
5905 *******************************************************************************/
5906
5907 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
5908 {
5909 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5910         java_nio_DirectByteBufferImpl *nbuf;
5911 # if SIZEOF_VOID_P == 8
5912         gnu_classpath_Pointer64       *address;
5913 # else
5914         gnu_classpath_Pointer32       *address;
5915 # endif
5916
5917         STATISTICS(jniinvokation());
5918
5919         if (!builtin_instanceof(buf, class_java_nio_Buffer))
5920                 return NULL;
5921
5922         nbuf = (java_nio_DirectByteBufferImpl *) buf;
5923
5924 # if SIZEOF_VOID_P == 8
5925         address = (gnu_classpath_Pointer64 *) nbuf->address;
5926 # else
5927         address = (gnu_classpath_Pointer32 *) nbuf->address;
5928 # endif
5929
5930         if (address == NULL)
5931                 return NULL;
5932
5933         return (void *) address->data;
5934 #else
5935         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
5936
5937         /* keep compiler happy */
5938
5939         return NULL;
5940 #endif
5941 }
5942
5943
5944 /* GetDirectBufferCapacity *****************************************************
5945
5946    Fetches and returns the capacity in bytes of the memory region
5947    referenced by the given direct java.nio.Buffer.
5948
5949 *******************************************************************************/
5950
5951 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5952 {
5953 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
5954         java_objectheader *o;
5955         java_nio_Buffer   *nbuf;
5956
5957         STATISTICS(jniinvokation());
5958
5959         o = (java_objectheader *) buf;
5960
5961         if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
5962                 return -1;
5963
5964         nbuf = (java_nio_Buffer *) o;
5965
5966         return (jlong) nbuf->cap;
5967 #else
5968         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
5969
5970         /* keep compiler happy */
5971
5972         return 0;
5973 #endif
5974 }
5975
5976
5977 /* DestroyJavaVM ***************************************************************
5978
5979    Unloads a Java VM and reclaims its resources. Only the main thread
5980    can unload the VM. The system waits until the main thread is only
5981    remaining user thread before it destroys the VM.
5982
5983 *******************************************************************************/
5984
5985 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
5986 {
5987         s4 status;
5988
5989         STATISTICS(jniinvokation());
5990
5991     status = vm_destroy(vm);
5992
5993         return status;
5994 }
5995
5996
5997 /* AttachCurrentThread *********************************************************
5998
5999    Attaches the current thread to a Java VM. Returns a JNI interface
6000    pointer in the JNIEnv argument.
6001
6002    Trying to attach a thread that is already attached is a no-op.
6003
6004    A native thread cannot be attached simultaneously to two Java VMs.
6005
6006    When a thread is attached to the VM, the context class loader is
6007    the bootstrap loader.
6008
6009 *******************************************************************************/
6010
6011 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
6012 {
6013         JavaVMAttachArgs *vm_aargs;
6014
6015 #if defined(ENABLE_THREADS)
6016         if (threads_get_current_threadobject() == NULL) {
6017                 vm_aargs = (JavaVMAttachArgs *) thr_args;
6018
6019                 if (vm_aargs != NULL) {
6020                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
6021                                 (vm_aargs->version != JNI_VERSION_1_4))
6022                                 return JNI_EVERSION;
6023                 }
6024
6025                 if (!threads_attach_current_thread(vm_aargs, false))
6026                         return JNI_ERR;
6027
6028                 if (!jni_init_localref_table())
6029                         return JNI_ERR;
6030         }
6031 #endif
6032
6033         *p_env = _Jv_env;
6034
6035         return JNI_OK;
6036 }
6037
6038
6039 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
6040 {
6041         STATISTICS(jniinvokation());
6042
6043         return jni_attach_current_thread(p_env, thr_args, false);
6044 }
6045
6046
6047 /* DetachCurrentThread *********************************************************
6048
6049    Detaches the current thread from a Java VM. All Java monitors held
6050    by this thread are released. All Java threads waiting for this
6051    thread to die are notified.
6052
6053    In JDK 1.1, the main thread cannot be detached from the VM. It must
6054    call DestroyJavaVM to unload the entire VM.
6055
6056    In the JDK, the main thread can be detached from the VM.
6057
6058    The main thread, which is the thread that created the Java VM,
6059    cannot be detached from the VM. Instead, the main thread must call
6060    JNI_DestroyJavaVM() to unload the entire VM.
6061
6062 *******************************************************************************/
6063
6064 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
6065 {
6066 #if defined(ENABLE_THREADS)
6067         threadobject *thread;
6068
6069         STATISTICS(jniinvokation());
6070
6071         thread = threads_get_current_threadobject();
6072
6073         if (thread == NULL)
6074                 return JNI_ERR;
6075
6076         if (!jni_free_localref_table())
6077                 return JNI_ERR;
6078
6079         if (!threads_detach_thread(thread))
6080                 return JNI_ERR;
6081 #endif
6082
6083         return JNI_OK;
6084 }
6085
6086
6087 /* GetEnv **********************************************************************
6088
6089    If the current thread is not attached to the VM, sets *env to NULL,
6090    and returns JNI_EDETACHED. If the specified version is not
6091    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
6092    sets *env to the appropriate interface, and returns JNI_OK.
6093
6094 *******************************************************************************/
6095
6096 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
6097 {
6098         STATISTICS(jniinvokation());
6099
6100 #if defined(ENABLE_THREADS)
6101         if (threads_get_current_threadobject() == NULL) {
6102                 *env = NULL;
6103
6104                 return JNI_EDETACHED;
6105         }
6106 #endif
6107
6108         /* check the JNI version */
6109
6110         switch (version) {
6111         case JNI_VERSION_1_1:
6112         case JNI_VERSION_1_2:
6113         case JNI_VERSION_1_4:
6114                 *env = _Jv_env;
6115                 return JNI_OK;
6116
6117         default:
6118                 ;
6119         }
6120
6121 #if defined(ENABLE_JVMTI)
6122         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
6123                 == JVMTI_VERSION_INTERFACE_JVMTI) {
6124
6125                 *env = (void *) jvmti_new_environment();
6126
6127                 if (env != NULL)
6128                         return JNI_OK;
6129         }
6130 #endif
6131         
6132         *env = NULL;
6133
6134         return JNI_EVERSION;
6135 }
6136
6137
6138 /* AttachCurrentThreadAsDaemon *************************************************
6139
6140    Same semantics as AttachCurrentThread, but the newly-created
6141    java.lang.Thread instance is a daemon.
6142
6143    If the thread has already been attached via either
6144    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
6145    simply sets the value pointed to by penv to the JNIEnv of the
6146    current thread. In this case neither AttachCurrentThread nor this
6147    routine have any effect on the daemon status of the thread.
6148
6149 *******************************************************************************/
6150
6151 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
6152 {
6153         STATISTICS(jniinvokation());
6154
6155         return jni_attach_current_thread(penv, args, true);
6156 }
6157
6158
6159 /* JNI invocation table *******************************************************/
6160
6161 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
6162         NULL,
6163         NULL,
6164         NULL,
6165
6166         _Jv_JNI_DestroyJavaVM,
6167         _Jv_JNI_AttachCurrentThread,
6168         _Jv_JNI_DetachCurrentThread,
6169         _Jv_JNI_GetEnv,
6170         _Jv_JNI_AttachCurrentThreadAsDaemon
6171 };
6172
6173
6174 /* JNI function table *********************************************************/
6175
6176 struct JNINativeInterface_ _Jv_JNINativeInterface = {
6177         NULL,
6178         NULL,
6179         NULL,
6180         NULL,    
6181         _Jv_JNI_GetVersion,
6182
6183         _Jv_JNI_DefineClass,
6184         _Jv_JNI_FindClass,
6185         _Jv_JNI_FromReflectedMethod,
6186         _Jv_JNI_FromReflectedField,
6187         _Jv_JNI_ToReflectedMethod,
6188         _Jv_JNI_GetSuperclass,
6189         _Jv_JNI_IsAssignableFrom,
6190         _Jv_JNI_ToReflectedField,
6191
6192         _Jv_JNI_Throw,
6193         _Jv_JNI_ThrowNew,
6194         _Jv_JNI_ExceptionOccurred,
6195         _Jv_JNI_ExceptionDescribe,
6196         _Jv_JNI_ExceptionClear,
6197         _Jv_JNI_FatalError,
6198         _Jv_JNI_PushLocalFrame,
6199         _Jv_JNI_PopLocalFrame,
6200
6201         _Jv_JNI_NewGlobalRef,
6202         _Jv_JNI_DeleteGlobalRef,
6203         _Jv_JNI_DeleteLocalRef,
6204         _Jv_JNI_IsSameObject,
6205         _Jv_JNI_NewLocalRef,
6206         _Jv_JNI_EnsureLocalCapacity,
6207
6208         _Jv_JNI_AllocObject,
6209         _Jv_JNI_NewObject,
6210         _Jv_JNI_NewObjectV,
6211         _Jv_JNI_NewObjectA,
6212
6213         _Jv_JNI_GetObjectClass,
6214         _Jv_JNI_IsInstanceOf,
6215
6216         _Jv_JNI_GetMethodID,
6217
6218         _Jv_JNI_CallObjectMethod,
6219         _Jv_JNI_CallObjectMethodV,
6220         _Jv_JNI_CallObjectMethodA,
6221         _Jv_JNI_CallBooleanMethod,
6222         _Jv_JNI_CallBooleanMethodV,
6223         _Jv_JNI_CallBooleanMethodA,
6224         _Jv_JNI_CallByteMethod,
6225         _Jv_JNI_CallByteMethodV,
6226         _Jv_JNI_CallByteMethodA,
6227         _Jv_JNI_CallCharMethod,
6228         _Jv_JNI_CallCharMethodV,
6229         _Jv_JNI_CallCharMethodA,
6230         _Jv_JNI_CallShortMethod,
6231         _Jv_JNI_CallShortMethodV,
6232         _Jv_JNI_CallShortMethodA,
6233         _Jv_JNI_CallIntMethod,
6234         _Jv_JNI_CallIntMethodV,
6235         _Jv_JNI_CallIntMethodA,
6236         _Jv_JNI_CallLongMethod,
6237         _Jv_JNI_CallLongMethodV,
6238         _Jv_JNI_CallLongMethodA,
6239         _Jv_JNI_CallFloatMethod,
6240         _Jv_JNI_CallFloatMethodV,
6241         _Jv_JNI_CallFloatMethodA,
6242         _Jv_JNI_CallDoubleMethod,
6243         _Jv_JNI_CallDoubleMethodV,
6244         _Jv_JNI_CallDoubleMethodA,
6245         _Jv_JNI_CallVoidMethod,
6246         _Jv_JNI_CallVoidMethodV,
6247         _Jv_JNI_CallVoidMethodA,
6248
6249         _Jv_JNI_CallNonvirtualObjectMethod,
6250         _Jv_JNI_CallNonvirtualObjectMethodV,
6251         _Jv_JNI_CallNonvirtualObjectMethodA,
6252         _Jv_JNI_CallNonvirtualBooleanMethod,
6253         _Jv_JNI_CallNonvirtualBooleanMethodV,
6254         _Jv_JNI_CallNonvirtualBooleanMethodA,
6255         _Jv_JNI_CallNonvirtualByteMethod,
6256         _Jv_JNI_CallNonvirtualByteMethodV,
6257         _Jv_JNI_CallNonvirtualByteMethodA,
6258         _Jv_JNI_CallNonvirtualCharMethod,
6259         _Jv_JNI_CallNonvirtualCharMethodV,
6260         _Jv_JNI_CallNonvirtualCharMethodA,
6261         _Jv_JNI_CallNonvirtualShortMethod,
6262         _Jv_JNI_CallNonvirtualShortMethodV,
6263         _Jv_JNI_CallNonvirtualShortMethodA,
6264         _Jv_JNI_CallNonvirtualIntMethod,
6265         _Jv_JNI_CallNonvirtualIntMethodV,
6266         _Jv_JNI_CallNonvirtualIntMethodA,
6267         _Jv_JNI_CallNonvirtualLongMethod,
6268         _Jv_JNI_CallNonvirtualLongMethodV,
6269         _Jv_JNI_CallNonvirtualLongMethodA,
6270         _Jv_JNI_CallNonvirtualFloatMethod,
6271         _Jv_JNI_CallNonvirtualFloatMethodV,
6272         _Jv_JNI_CallNonvirtualFloatMethodA,
6273         _Jv_JNI_CallNonvirtualDoubleMethod,
6274         _Jv_JNI_CallNonvirtualDoubleMethodV,
6275         _Jv_JNI_CallNonvirtualDoubleMethodA,
6276         _Jv_JNI_CallNonvirtualVoidMethod,
6277         _Jv_JNI_CallNonvirtualVoidMethodV,
6278         _Jv_JNI_CallNonvirtualVoidMethodA,
6279
6280         _Jv_JNI_GetFieldID,
6281
6282         _Jv_JNI_GetObjectField,
6283         _Jv_JNI_GetBooleanField,
6284         _Jv_JNI_GetByteField,
6285         _Jv_JNI_GetCharField,
6286         _Jv_JNI_GetShortField,
6287         _Jv_JNI_GetIntField,
6288         _Jv_JNI_GetLongField,
6289         _Jv_JNI_GetFloatField,
6290         _Jv_JNI_GetDoubleField,
6291         _Jv_JNI_SetObjectField,
6292         _Jv_JNI_SetBooleanField,
6293         _Jv_JNI_SetByteField,
6294         _Jv_JNI_SetCharField,
6295         _Jv_JNI_SetShortField,
6296         _Jv_JNI_SetIntField,
6297         _Jv_JNI_SetLongField,
6298         _Jv_JNI_SetFloatField,
6299         _Jv_JNI_SetDoubleField,
6300
6301         _Jv_JNI_GetStaticMethodID,
6302
6303         _Jv_JNI_CallStaticObjectMethod,
6304         _Jv_JNI_CallStaticObjectMethodV,
6305         _Jv_JNI_CallStaticObjectMethodA,
6306         _Jv_JNI_CallStaticBooleanMethod,
6307         _Jv_JNI_CallStaticBooleanMethodV,
6308         _Jv_JNI_CallStaticBooleanMethodA,
6309         _Jv_JNI_CallStaticByteMethod,
6310         _Jv_JNI_CallStaticByteMethodV,
6311         _Jv_JNI_CallStaticByteMethodA,
6312         _Jv_JNI_CallStaticCharMethod,
6313         _Jv_JNI_CallStaticCharMethodV,
6314         _Jv_JNI_CallStaticCharMethodA,
6315         _Jv_JNI_CallStaticShortMethod,
6316         _Jv_JNI_CallStaticShortMethodV,
6317         _Jv_JNI_CallStaticShortMethodA,
6318         _Jv_JNI_CallStaticIntMethod,
6319         _Jv_JNI_CallStaticIntMethodV,
6320         _Jv_JNI_CallStaticIntMethodA,
6321         _Jv_JNI_CallStaticLongMethod,
6322         _Jv_JNI_CallStaticLongMethodV,
6323         _Jv_JNI_CallStaticLongMethodA,
6324         _Jv_JNI_CallStaticFloatMethod,
6325         _Jv_JNI_CallStaticFloatMethodV,
6326         _Jv_JNI_CallStaticFloatMethodA,
6327         _Jv_JNI_CallStaticDoubleMethod,
6328         _Jv_JNI_CallStaticDoubleMethodV,
6329         _Jv_JNI_CallStaticDoubleMethodA,
6330         _Jv_JNI_CallStaticVoidMethod,
6331         _Jv_JNI_CallStaticVoidMethodV,
6332         _Jv_JNI_CallStaticVoidMethodA,
6333
6334         _Jv_JNI_GetStaticFieldID,
6335
6336         _Jv_JNI_GetStaticObjectField,
6337         _Jv_JNI_GetStaticBooleanField,
6338         _Jv_JNI_GetStaticByteField,
6339         _Jv_JNI_GetStaticCharField,
6340         _Jv_JNI_GetStaticShortField,
6341         _Jv_JNI_GetStaticIntField,
6342         _Jv_JNI_GetStaticLongField,
6343         _Jv_JNI_GetStaticFloatField,
6344         _Jv_JNI_GetStaticDoubleField,
6345         _Jv_JNI_SetStaticObjectField,
6346         _Jv_JNI_SetStaticBooleanField,
6347         _Jv_JNI_SetStaticByteField,
6348         _Jv_JNI_SetStaticCharField,
6349         _Jv_JNI_SetStaticShortField,
6350         _Jv_JNI_SetStaticIntField,
6351         _Jv_JNI_SetStaticLongField,
6352         _Jv_JNI_SetStaticFloatField,
6353         _Jv_JNI_SetStaticDoubleField,
6354
6355         _Jv_JNI_NewString,
6356         _Jv_JNI_GetStringLength,
6357         _Jv_JNI_GetStringChars,
6358         _Jv_JNI_ReleaseStringChars,
6359
6360         _Jv_JNI_NewStringUTF,
6361         _Jv_JNI_GetStringUTFLength,
6362         _Jv_JNI_GetStringUTFChars,
6363         _Jv_JNI_ReleaseStringUTFChars,
6364
6365         _Jv_JNI_GetArrayLength,
6366
6367         _Jv_JNI_NewObjectArray,
6368         _Jv_JNI_GetObjectArrayElement,
6369         _Jv_JNI_SetObjectArrayElement,
6370
6371         _Jv_JNI_NewBooleanArray,
6372         _Jv_JNI_NewByteArray,
6373         _Jv_JNI_NewCharArray,
6374         _Jv_JNI_NewShortArray,
6375         _Jv_JNI_NewIntArray,
6376         _Jv_JNI_NewLongArray,
6377         _Jv_JNI_NewFloatArray,
6378         _Jv_JNI_NewDoubleArray,
6379
6380         _Jv_JNI_GetBooleanArrayElements,
6381         _Jv_JNI_GetByteArrayElements,
6382         _Jv_JNI_GetCharArrayElements,
6383         _Jv_JNI_GetShortArrayElements,
6384         _Jv_JNI_GetIntArrayElements,
6385         _Jv_JNI_GetLongArrayElements,
6386         _Jv_JNI_GetFloatArrayElements,
6387         _Jv_JNI_GetDoubleArrayElements,
6388
6389         _Jv_JNI_ReleaseBooleanArrayElements,
6390         _Jv_JNI_ReleaseByteArrayElements,
6391         _Jv_JNI_ReleaseCharArrayElements,
6392         _Jv_JNI_ReleaseShortArrayElements,
6393         _Jv_JNI_ReleaseIntArrayElements,
6394         _Jv_JNI_ReleaseLongArrayElements,
6395         _Jv_JNI_ReleaseFloatArrayElements,
6396         _Jv_JNI_ReleaseDoubleArrayElements,
6397
6398         _Jv_JNI_GetBooleanArrayRegion,
6399         _Jv_JNI_GetByteArrayRegion,
6400         _Jv_JNI_GetCharArrayRegion,
6401         _Jv_JNI_GetShortArrayRegion,
6402         _Jv_JNI_GetIntArrayRegion,
6403         _Jv_JNI_GetLongArrayRegion,
6404         _Jv_JNI_GetFloatArrayRegion,
6405         _Jv_JNI_GetDoubleArrayRegion,
6406         _Jv_JNI_SetBooleanArrayRegion,
6407         _Jv_JNI_SetByteArrayRegion,
6408         _Jv_JNI_SetCharArrayRegion,
6409         _Jv_JNI_SetShortArrayRegion,
6410         _Jv_JNI_SetIntArrayRegion,
6411         _Jv_JNI_SetLongArrayRegion,
6412         _Jv_JNI_SetFloatArrayRegion,
6413         _Jv_JNI_SetDoubleArrayRegion,
6414
6415         _Jv_JNI_RegisterNatives,
6416         _Jv_JNI_UnregisterNatives,
6417
6418         _Jv_JNI_MonitorEnter,
6419         _Jv_JNI_MonitorExit,
6420
6421         _Jv_JNI_GetJavaVM,
6422
6423         /* new JNI 1.2 functions */
6424
6425         _Jv_JNI_GetStringRegion,
6426         _Jv_JNI_GetStringUTFRegion,
6427
6428         _Jv_JNI_GetPrimitiveArrayCritical,
6429         _Jv_JNI_ReleasePrimitiveArrayCritical,
6430
6431         _Jv_JNI_GetStringCritical,
6432         _Jv_JNI_ReleaseStringCritical,
6433
6434         _Jv_JNI_NewWeakGlobalRef,
6435         _Jv_JNI_DeleteWeakGlobalRef,
6436
6437         _Jv_JNI_ExceptionCheck,
6438
6439         /* new JNI 1.4 functions */
6440
6441         _Jv_JNI_NewDirectByteBuffer,
6442         _Jv_JNI_GetDirectBufferAddress,
6443         _Jv_JNI_GetDirectBufferCapacity
6444 };
6445
6446
6447 /* Invocation API Functions ***************************************************/
6448
6449 /* JNI_GetDefaultJavaVMInitArgs ************************************************
6450
6451    Returns a default configuration for the Java VM.
6452
6453 *******************************************************************************/
6454
6455 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
6456 {
6457         JavaVMInitArgs *_vm_args;
6458
6459         _vm_args = (JavaVMInitArgs *) vm_args;
6460
6461         /* GNU classpath currently supports JNI 1.2 */
6462
6463         switch (_vm_args->version) {
6464     case JNI_VERSION_1_1:
6465                 _vm_args->version = JNI_VERSION_1_1;
6466                 break;
6467
6468     case JNI_VERSION_1_2:
6469     case JNI_VERSION_1_4:
6470                 _vm_args->ignoreUnrecognized = JNI_FALSE;
6471                 _vm_args->options = NULL;
6472                 _vm_args->nOptions = 0;
6473                 break;
6474
6475     default:
6476                 return -1;
6477         }
6478   
6479         return 0;
6480 }
6481
6482
6483 /* JNI_GetCreatedJavaVMs *******************************************************
6484
6485    Returns all Java VMs that have been created. Pointers to VMs are written in
6486    the buffer vmBuf in the order they are created. At most bufLen number of
6487    entries will be written. The total number of created VMs is returned in
6488    *nVMs.
6489
6490 *******************************************************************************/
6491
6492 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
6493 {
6494         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
6495
6496         return 0;
6497 }
6498
6499
6500 /* JNI_CreateJavaVM ************************************************************
6501
6502    Loads and initializes a Java VM. The current thread becomes the main thread.
6503    Sets the env argument to the JNI interface pointer of the main thread.
6504
6505 *******************************************************************************/
6506
6507 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
6508 {
6509         /* actually create the JVM */
6510
6511         if (!vm_createjvm(p_vm, p_env, vm_args))
6512                 return JNI_ERR;
6513
6514         return JNI_OK;
6515 }
6516
6517
6518 /*
6519  * These are local overrides for various environment variables in Emacs.
6520  * Please do not remove this and leave it at the end of the file, where
6521  * Emacs will automagically detect them.
6522  * ---------------------------------------------------------------------
6523  * Local variables:
6524  * mode: c
6525  * indent-tabs-mode: t
6526  * c-basic-offset: 4
6527  * tab-width: 4
6528  * End:
6529  * vim:noexpandtab:sw=4:ts=4:
6530  */