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