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