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