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