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