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