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