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