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