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