* src/native/jni.c (_Jv_JNI_FindClass) [ENABLE_JAVAME_CLDC1_1]:
[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 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32 #include <string.h>
33
34 #include "vm/types.h"
35
36 #include "mm/gc-common.h"
37 #include "mm/memory.h"
38
39 #include "native/jni.h"
40 #include "native/llni.h"
41 #include "native/localref.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_String.h"
58 #include "native/include/java_lang_Throwable.h"
59
60 #if defined(ENABLE_JAVASE)
61 # if defined(WITH_CLASSPATH_SUN)
62 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
63 # endif
64
65 # include "native/include/java_lang_ClassLoader.h"
66
67 # include "native/include/java_lang_reflect_Constructor.h"
68 # include "native/include/java_lang_reflect_Field.h"
69 # include "native/include/java_lang_reflect_Method.h"
70
71 # include "native/include/java_nio_Buffer.h"
72
73 # if defined(WITH_CLASSPATH_GNU)
74 #  include "native/include/java_nio_DirectByteBufferImpl.h"
75 # endif
76 #endif
77
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
80 #endif
81
82 #include "native/vm/java_lang_Class.h"
83
84 #if defined(ENABLE_JAVASE)
85 # include "native/vm/java_lang_ClassLoader.h"
86 # include "native/vm/reflect.h"
87 #endif
88
89 #include "threads/lock-common.h"
90 #include "threads/threads-common.h"
91
92 #include "toolbox/logging.h"
93
94 #include "vm/builtin.h"
95 #include "vm/exceptions.h"
96 #include "vm/global.h"
97 #include "vm/initialize.h"
98 #include "vm/primitive.h"
99 #include "vm/resolve.h"
100 #include "vm/stringlocal.h"
101 #include "vm/vm.h"
102
103 #include "vm/jit/asmpart.h"
104 #include "vm/jit/jit.h"
105 #include "vm/jit/stacktrace.h"
106
107 #include "vmcore/loader.h"
108 #include "vmcore/options.h"
109 #include "vmcore/statistics.h"
110
111
112 /* debug **********************************************************************/
113
114 #if !defined(NDEBUG)
115 # define TRACEJNICALLS(format, ...) \
116     do { \
117         if (opt_TraceJNICalls) { \
118             log_println((format), __VA_ARGS__); \
119         } \
120     } while (0)
121 #else
122 # define TRACEJNICALLS(format, ...)
123 #endif
124
125
126 /* global variables ***********************************************************/
127
128 /* global reference table *****************************************************/
129
130 /* hashsize must be power of 2 */
131
132 #define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
133
134 static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
135
136
137 /* direct buffer stuff ********************************************************/
138
139 #if defined(ENABLE_JAVASE)
140 static classinfo *class_java_nio_Buffer;
141
142 # if defined(WITH_CLASSPATH_GNU)
143
144 static classinfo *class_java_nio_DirectByteBufferImpl;
145 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
146
147 #  if SIZEOF_VOID_P == 8
148 static classinfo *class_gnu_classpath_Pointer64;
149 #  else
150 static classinfo *class_gnu_classpath_Pointer32;
151 #  endif
152
153 static methodinfo *dbbirw_init;
154
155 # elif defined(WITH_CLASSPATH_SUN)
156
157 static classinfo *class_sun_nio_ch_DirectBuffer;
158 static classinfo *class_java_nio_DirectByteBuffer;
159
160 static methodinfo *dbb_init;
161
162 # endif
163 #endif
164
165
166 /* accessing instance fields macros *******************************************/
167
168 #define SET_FIELD(o,type,f,value) \
169     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
170
171 #define GET_FIELD(o,type,f) \
172     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
173
174
175 /* some forward declarations **************************************************/
176
177 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
178
179
180 /* jni_init ********************************************************************
181
182    Initialize the JNI subsystem.
183
184 *******************************************************************************/
185
186 bool jni_init(void)
187 {
188         /* create global ref hashtable */
189
190         hashtable_global_ref = NEW(hashtable);
191
192         hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
193
194
195 #if defined(ENABLE_JAVASE)
196         /* Direct buffer stuff. */
197
198         if (!(class_java_nio_Buffer =
199                   load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
200                 !link_class(class_java_nio_Buffer))
201                 return false;
202
203 # if defined(WITH_CLASSPATH_GNU)
204
205         if (!(class_java_nio_DirectByteBufferImpl =
206                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
207                 !link_class(class_java_nio_DirectByteBufferImpl))
208                 return false;
209
210         if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
211                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
212                 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
213                 return false;
214
215         if (!(dbbirw_init =
216                 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
217                                                         utf_init,
218                                                         utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
219                 return false;
220
221 #  if SIZEOF_VOID_P == 8
222         if (!(class_gnu_classpath_Pointer64 =
223                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
224                 !link_class(class_gnu_classpath_Pointer64))
225                 return false;
226 #  else
227         if (!(class_gnu_classpath_Pointer32 =
228                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
229                 !link_class(class_gnu_classpath_Pointer32))
230                 return false;
231 #  endif
232
233 # elif defined(WITH_CLASSPATH_SUN)
234
235         if (!(class_sun_nio_ch_DirectBuffer =
236                   load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
237                 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
238
239         if (!link_class(class_sun_nio_ch_DirectBuffer))
240                 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
241
242         if (!(class_java_nio_DirectByteBuffer =
243                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
244                 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
245
246         if (!link_class(class_java_nio_DirectByteBuffer))
247                 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
248
249         if (!(dbb_init =
250                   class_resolvemethod(class_java_nio_DirectByteBuffer,
251                                                           utf_init,
252                                                           utf_new_char("(JI)V"))))
253                 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
254
255 # endif
256
257 #endif /* defined(ENABLE_JAVASE) */
258
259         return true;
260 }
261
262
263 /* _Jv_jni_CallObjectMethod ****************************************************
264
265    Internal function to call Java Object methods.
266
267 *******************************************************************************/
268
269 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
270                                                                                            vftbl_t *vftbl,
271                                                                                            methodinfo *m, va_list ap)
272 {
273         methodinfo    *resm;
274         java_handle_t *ro;
275
276         STATISTICS(jniinvokation());
277
278         if (m == NULL) {
279                 exceptions_throw_nullpointerexception();
280                 return NULL;
281         }
282
283         /* Class initialization is done by the JIT compiler.  This is ok
284            since a static method always belongs to the declaring class. */
285
286         if (m->flags & ACC_STATIC) {
287                 /* For static methods we reset the object. */
288
289                 if (o != NULL)
290                         o = NULL;
291
292                 /* for convenience */
293
294                 resm = m;
295
296         } else {
297                 /* For instance methods we make a virtual function table lookup. */
298
299                 resm = method_vftbl_lookup(vftbl, m);
300         }
301
302         STATISTICS(jnicallXmethodnvokation());
303
304         ro = vm_call_method_valist(resm, o, ap);
305
306         return ro;
307 }
308
309
310 /* _Jv_jni_CallObjectMethodA ***************************************************
311
312    Internal function to call Java Object methods.
313
314 *******************************************************************************/
315
316 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
317                                                                                                 vftbl_t *vftbl,
318                                                                                                 methodinfo *m,
319                                                                                                 const jvalue *args)
320 {
321         methodinfo    *resm;
322         java_handle_t *ro;
323
324         STATISTICS(jniinvokation());
325
326         if (m == NULL) {
327                 exceptions_throw_nullpointerexception();
328                 return NULL;
329         }
330
331         /* Class initialization is done by the JIT compiler.  This is ok
332            since a static method always belongs to the declaring class. */
333
334         if (m->flags & ACC_STATIC) {
335                 /* For static methods we reset the object. */
336
337                 if (o != NULL)
338                         o = NULL;
339
340                 /* for convenience */
341
342                 resm = m;
343
344         } else {
345                 /* For instance methods we make a virtual function table lookup. */
346
347                 resm = method_vftbl_lookup(vftbl, m);
348         }
349
350         STATISTICS(jnicallXmethodnvokation());
351
352         ro = vm_call_method_jvalue(resm, o, args);
353
354         return ro;
355 }
356
357
358 /* _Jv_jni_CallIntMethod *******************************************************
359
360    Internal function to call Java integer class methods (boolean,
361    byte, char, short, int).
362
363 *******************************************************************************/
364
365 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
366                                                                   methodinfo *m, va_list ap)
367 {
368         methodinfo *resm;
369         jint        i;
370
371         STATISTICS(jniinvokation());
372
373         if (m == NULL) {
374                 exceptions_throw_nullpointerexception();
375                 return 0;
376         }
377         
378         /* Class initialization is done by the JIT compiler.  This is ok
379            since a static method always belongs to the declaring class. */
380
381         if (m->flags & ACC_STATIC) {
382                 /* For static methods we reset the object. */
383
384                 if (o != NULL)
385                         o = NULL;
386
387                 /* for convenience */
388
389                 resm = m;
390
391         } else {
392                 /* For instance methods we make a virtual function table lookup. */
393
394                 resm = method_vftbl_lookup(vftbl, m);
395         }
396
397         STATISTICS(jnicallXmethodnvokation());
398
399         i = vm_call_method_int_valist(resm, o, ap);
400
401         return i;
402 }
403
404
405 /* _Jv_jni_CallIntMethodA ******************************************************
406
407    Internal function to call Java integer class methods (boolean,
408    byte, char, short, int).
409
410 *******************************************************************************/
411
412 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
413                                                                    methodinfo *m, const jvalue *args)
414 {
415         methodinfo *resm;
416         jint        i;
417
418         STATISTICS(jniinvokation());
419
420         if (m == NULL) {
421                 exceptions_throw_nullpointerexception();
422                 return 0;
423         }
424         
425         /* Class initialization is done by the JIT compiler.  This is ok
426            since a static method always belongs to the declaring class. */
427
428         if (m->flags & ACC_STATIC) {
429                 /* For static methods we reset the object. */
430
431                 if (o != NULL)
432                         o = NULL;
433
434                 /* for convenience */
435
436                 resm = m;
437
438         } else {
439                 /* For instance methods we make a virtual function table lookup. */
440
441                 resm = method_vftbl_lookup(vftbl, m);
442         }
443
444         STATISTICS(jnicallXmethodnvokation());
445
446         i = vm_call_method_int_jvalue(resm, o, args);
447
448         return i;
449 }
450
451
452 /* _Jv_jni_CallLongMethod ******************************************************
453
454    Internal function to call Java long methods.
455
456 *******************************************************************************/
457
458 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
459                                                                         methodinfo *m, va_list ap)
460 {
461         methodinfo *resm;
462         jlong       l;
463
464         STATISTICS(jniinvokation());
465
466         if (m == NULL) {
467                 exceptions_throw_nullpointerexception();
468                 return 0;
469         }
470
471         /* Class initialization is done by the JIT compiler.  This is ok
472            since a static method always belongs to the declaring class. */
473
474         if (m->flags & ACC_STATIC) {
475                 /* For static methods we reset the object. */
476
477                 if (o != NULL)
478                         o = NULL;
479
480                 /* for convenience */
481
482                 resm = m;
483
484         } else {
485                 /* For instance methods we make a virtual function table lookup. */
486
487                 resm = method_vftbl_lookup(vftbl, m);
488         }
489
490         STATISTICS(jnicallXmethodnvokation());
491
492         l = vm_call_method_long_valist(resm, o, ap);
493
494         return l;
495 }
496
497
498 /* _Jv_jni_CallLongMethodA *****************************************************
499
500    Internal function to call Java long methods.
501
502 *******************************************************************************/
503
504 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
505                                                                          methodinfo *m, const jvalue *args)
506 {
507         methodinfo *resm;
508         jlong       l;
509
510         STATISTICS(jniinvokation());
511
512         if (m == NULL) {
513                 exceptions_throw_nullpointerexception();
514                 return 0;
515         }
516
517         /* Class initialization is done by the JIT compiler.  This is ok
518            since a static method always belongs to the declaring class. */
519
520         if (m->flags & ACC_STATIC) {
521                 /* For static methods we reset the object. */
522
523                 if (o != NULL)
524                         o = NULL;
525
526                 /* for convenience */
527
528                 resm = m;
529         }
530         else {
531                 /* For instance methods we make a virtual function table lookup. */
532
533                 resm = method_vftbl_lookup(vftbl, m);
534         }
535
536         STATISTICS(jnicallXmethodnvokation());
537
538         l = vm_call_method_long_jvalue(resm, o, args);
539
540         return l;
541 }
542
543
544 /* _Jv_jni_CallFloatMethod *****************************************************
545
546    Internal function to call Java float methods.
547
548 *******************************************************************************/
549
550 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
551                                                                           methodinfo *m, va_list ap)
552 {
553         methodinfo *resm;
554         jfloat      f;
555
556         /* Class initialization is done by the JIT compiler.  This is ok
557            since a static method always belongs to the declaring class. */
558
559         if (m->flags & ACC_STATIC) {
560                 /* For static methods we reset the object. */
561
562                 if (o != NULL)
563                         o = NULL;
564
565                 /* for convenience */
566
567                 resm = m;
568
569         } else {
570                 /* For instance methods we make a virtual function table lookup. */
571
572                 resm = method_vftbl_lookup(vftbl, m);
573         }
574
575         STATISTICS(jnicallXmethodnvokation());
576
577         f = vm_call_method_float_valist(resm, o, ap);
578
579         return f;
580 }
581
582
583 /* _Jv_jni_CallFloatMethodA ****************************************************
584
585    Internal function to call Java float methods.
586
587 *******************************************************************************/
588
589 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
590                                                                            methodinfo *m, const jvalue *args)
591 {
592         methodinfo *resm;
593         jfloat      f;
594
595         /* Class initialization is done by the JIT compiler.  This is ok
596            since a static method always belongs to the declaring class. */
597
598         if (m->flags & ACC_STATIC) {
599                 /* For static methods we reset the object. */
600
601                 if (o != NULL)
602                         o = NULL;
603
604                 /* for convenience */
605
606                 resm = m;
607         }
608         else {
609                 /* For instance methods we make a virtual function table lookup. */
610
611                 resm = method_vftbl_lookup(vftbl, m);
612         }
613
614         STATISTICS(jnicallXmethodnvokation());
615
616         f = vm_call_method_float_jvalue(resm, o, args);
617
618         return f;
619 }
620
621
622 /* _Jv_jni_CallDoubleMethod ****************************************************
623
624    Internal function to call Java double methods.
625
626 *******************************************************************************/
627
628 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
629                                                                                 methodinfo *m, va_list ap)
630 {
631         methodinfo *resm;
632         jdouble     d;
633
634         /* Class initialization is done by the JIT compiler.  This is ok
635            since a static method always belongs to the declaring class. */
636
637         if (m->flags & ACC_STATIC) {
638                 /* For static methods we reset the object. */
639
640                 if (o != NULL)
641                         o = NULL;
642
643                 /* for convenience */
644
645                 resm = m;
646
647         } else {
648                 /* For instance methods we make a virtual function table lookup. */
649
650                 resm = method_vftbl_lookup(vftbl, m);
651         }
652
653         d = vm_call_method_double_valist(resm, o, ap);
654
655         return d;
656 }
657
658
659 /* _Jv_jni_CallDoubleMethodA ***************************************************
660
661    Internal function to call Java double methods.
662
663 *******************************************************************************/
664
665 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
666                                                                                  methodinfo *m, const jvalue *args)
667 {
668         methodinfo *resm;
669         jdouble     d;
670
671         /* Class initialization is done by the JIT compiler.  This is ok
672            since a static method always belongs to the declaring class. */
673
674         if (m->flags & ACC_STATIC) {
675                 /* For static methods we reset the object. */
676
677                 if (o != NULL)
678                         o = NULL;
679
680                 /* for convenience */
681
682                 resm = m;
683         }
684         else {
685                 /* For instance methods we make a virtual function table lookup. */
686
687                 resm = method_vftbl_lookup(vftbl, m);
688         }
689
690         d = vm_call_method_double_jvalue(resm, o, args);
691
692         return d;
693 }
694
695
696 /* _Jv_jni_CallVoidMethod ******************************************************
697
698    Internal function to call Java void methods.
699
700 *******************************************************************************/
701
702 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
703                                                                    methodinfo *m, va_list ap)
704 {       
705         methodinfo *resm;
706
707         if (m == NULL) {
708                 exceptions_throw_nullpointerexception();
709                 return;
710         }
711
712         /* Class initialization is done by the JIT compiler.  This is ok
713            since a static method always belongs to the declaring class. */
714
715         if (m->flags & ACC_STATIC) {
716                 /* For static methods we reset the object. */
717
718                 if (o != NULL)
719                         o = NULL;
720
721                 /* for convenience */
722
723                 resm = m;
724
725         } else {
726                 /* For instance methods we make a virtual function table lookup. */
727
728                 resm = method_vftbl_lookup(vftbl, m);
729         }
730
731         STATISTICS(jnicallXmethodnvokation());
732
733         (void) vm_call_method_valist(resm, o, ap);
734 }
735
736
737 /* _Jv_jni_CallVoidMethodA *****************************************************
738
739    Internal function to call Java void methods.
740
741 *******************************************************************************/
742
743 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
744                                                                         methodinfo *m, const jvalue *args)
745 {       
746         methodinfo *resm;
747
748         if (m == NULL) {
749                 exceptions_throw_nullpointerexception();
750                 return;
751         }
752
753         /* Class initialization is done by the JIT compiler.  This is ok
754            since a static method always belongs to the declaring class. */
755
756         if (m->flags & ACC_STATIC) {
757                 /* For static methods we reset the object. */
758
759                 if (o != NULL)
760                         o = NULL;
761
762                 /* for convenience */
763
764                 resm = m;
765
766         } else {
767                 /* For instance methods we make a virtual function table lookup. */
768
769                 resm = method_vftbl_lookup(vftbl, m);
770         }
771
772         STATISTICS(jnicallXmethodnvokation());
773
774         (void) vm_call_method_jvalue(resm, o, args);
775 }
776
777
778 /* _Jv_jni_invokeNative ********************************************************
779
780    Invoke a method on the given object with the given arguments.
781
782    For instance methods OBJ must be != NULL and the method is looked up
783    in the vftbl of the object.
784
785    For static methods, OBJ is ignored.
786
787 *******************************************************************************/
788
789 java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
790                                                                         java_handle_objectarray_t *params)
791 {
792         methodinfo    *resm;
793         java_handle_t *ro;
794         s4             argcount;
795         s4             paramcount;
796         java_handle_t *xptr;
797         int32_t        dumpsize;
798         uint64_t      *array;
799         imm_union          value;
800
801         if (m == NULL) {
802                 exceptions_throw_nullpointerexception();
803                 return NULL;
804         }
805
806         argcount = m->parseddesc->paramcount;
807         paramcount = argcount;
808
809         /* if method is non-static, remove the `this' pointer */
810
811         if (!(m->flags & ACC_STATIC))
812                 paramcount--;
813
814         /* For instance methods the object has to be an instance of the
815            class the method belongs to. For static methods the obj
816            parameter is ignored. */
817
818         if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
819                 exceptions_throw_illegalargumentexception();
820                 return NULL;
821         }
822
823         /* check if we got the right number of arguments */
824
825         if (((params == NULL) && (paramcount != 0)) ||
826                 (params && (LLNI_array_size(params) != paramcount))) 
827         {
828                 exceptions_throw_illegalargumentexception();
829                 return NULL;
830         }
831
832         /* for instance methods we need an object */
833
834         if (!(m->flags & ACC_STATIC) && (o == NULL)) {
835                 /* XXX not sure if that is the correct exception */
836                 exceptions_throw_nullpointerexception();
837                 return NULL;
838         }
839
840         /* for static methods, zero object to make subsequent code simpler */
841         if (m->flags & ACC_STATIC)
842                 o = NULL;
843
844         if (o != NULL) {
845                 /* for instance methods we must do a vftbl lookup */
846                 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
847         }
848         else {
849                 /* for static methods, just for convenience */
850                 resm = m;
851         }
852
853         /* mark start of dump memory area */
854
855         dumpsize = dump_size();
856
857         /* Fill the argument array from a object-array. */
858
859         array = vm_array_from_objectarray(resm, o, params);
860
861         /* The array can be NULL if we don't have any arguments to pass
862            and the architecture does not have any argument registers
863            (e.g. i386).  In that case we additionally check for an
864            exception thrown. */
865
866         if ((array == NULL) && (exceptions_get_exception() != NULL)) {
867                 /* release dump area */
868
869                 dump_release(dumpsize);
870
871                 return NULL;
872         }
873
874         switch (resm->parseddesc->returntype.decltype) {
875         case TYPE_VOID:
876                 (void) vm_call_array(resm, array);
877                 ro = NULL;
878                 break;
879
880         case PRIMITIVETYPE_BOOLEAN:
881         case PRIMITIVETYPE_BYTE:
882         case PRIMITIVETYPE_CHAR:
883         case PRIMITIVETYPE_SHORT:
884         case PRIMITIVETYPE_INT:
885                 value.i = vm_call_int_array(resm, array);
886                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
887                 break;
888
889         case PRIMITIVETYPE_LONG:
890                 value.l = vm_call_long_array(resm, array);
891                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
892                 break;
893
894         case PRIMITIVETYPE_FLOAT:
895                 value.f = vm_call_float_array(resm, array);
896                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
897                 break;
898
899         case PRIMITIVETYPE_DOUBLE:
900                 value.d = vm_call_double_array(resm, array);
901                 ro = primitive_box(resm->parseddesc->returntype.decltype, value);
902                 break;
903
904         case TYPE_ADR:
905                 ro = vm_call_array(resm, array);
906                 break;
907
908         default:
909                 vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
910         }
911
912         xptr = exceptions_get_exception();
913
914         if (xptr != NULL) {
915                 /* clear exception pointer, we are calling JIT code again */
916
917                 exceptions_clear_exception();
918
919                 exceptions_throw_invocationtargetexception(xptr);
920         }
921
922         /* release dump area */
923
924         dump_release(dumpsize);
925
926         return ro;
927 }
928
929
930 /* GetVersion ******************************************************************
931
932    Returns the major version number in the higher 16 bits and the
933    minor version number in the lower 16 bits.
934
935 *******************************************************************************/
936
937 jint _Jv_JNI_GetVersion(JNIEnv *env)
938 {
939         TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
940
941         /* We support JNI 1.6. */
942
943         return JNI_VERSION_1_6;
944 }
945
946
947 /* Class Operations ***********************************************************/
948
949 /* DefineClass *****************************************************************
950
951    Loads a class from a buffer of raw class data. The buffer
952    containing the raw class data is not referenced by the VM after the
953    DefineClass call returns, and it may be discarded if desired.
954
955 *******************************************************************************/
956
957 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
958                                                    const jbyte *buf, jsize bufLen)
959 {
960 #if defined(ENABLE_JAVASE)
961         utf             *u;
962         classloader     *cl;
963         classinfo       *c;
964         java_lang_Class *co;
965
966         TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
967
968         u  = utf_new_char(name);
969         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
970
971         c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
972
973         co = LLNI_classinfo_wrap(c);
974
975         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
976 #else
977         vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
978
979         /* keep compiler happy */
980
981         return 0;
982 #endif
983 }
984
985
986 /* FindClass *******************************************************************
987
988    This function loads a locally-defined class. It searches the
989    directories and zip files specified by the CLASSPATH environment
990    variable for the class with the specified name.
991
992 *******************************************************************************/
993
994 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
995 {
996 #if defined(ENABLE_JAVASE)
997
998         utf             *u;
999         classinfo       *cc;
1000         classinfo       *c;
1001         java_lang_Class *co;
1002
1003         TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1004
1005         u = utf_new_char_classname((char *) name);
1006
1007         /* Check stacktrace for classloader, if one found use it,
1008            otherwise use the system classloader. */
1009
1010         /* Quote from the JNI documentation:
1011          
1012            In the Java 2 Platform, FindClass locates the class loader
1013            associated with the current native method.  If the native code
1014            belongs to a system class, no class loader will be
1015            involved. Otherwise, the proper class loader will be invoked to
1016            load and link the named class. When FindClass is called through
1017            the Invocation Interface, there is no current native method or
1018            its associated class loader. In that case, the result of
1019            ClassLoader.getBaseClassLoader is used." */
1020
1021         cc = stacktrace_getCurrentClass();
1022
1023         if (cc == NULL)
1024                 c = load_class_from_sysloader(u);
1025         else
1026                 c = load_class_from_classloader(u, cc->classloader);
1027
1028         if (c == NULL)
1029                 return NULL;
1030
1031         if (!link_class(c))
1032                 return NULL;
1033
1034         co = LLNI_classinfo_wrap(c);
1035
1036         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1037
1038 #elif defined(ENABLE_JAVAME_CLDC1_1)
1039
1040         utf       *u;
1041         classinfo *c;
1042
1043         TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
1044
1045         u = utf_new_char_classname((char *) name);
1046         c = load_class_bootstrap(u);
1047
1048         if (c == NULL)
1049                 return NULL;
1050
1051         if (!link_class(c))
1052                 return NULL;
1053
1054         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
1055         
1056 #else
1057         vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1058
1059         /* keep compiler happy */
1060
1061         return NULL;
1062 #endif
1063 }
1064   
1065
1066 /* GetSuperclass ***************************************************************
1067
1068    If clazz represents any class other than the class Object, then
1069    this function returns the object that represents the superclass of
1070    the class specified by clazz.
1071
1072 *******************************************************************************/
1073  
1074 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1075 {
1076         classinfo       *c;
1077         classinfo       *super;
1078         java_lang_Class *co;
1079
1080         TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1081
1082         c = LLNI_classinfo_unwrap(sub);
1083
1084         if (c == NULL)
1085                 return NULL;
1086
1087         super = class_get_superclass(c);
1088
1089         co = LLNI_classinfo_wrap(super);
1090
1091         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1092 }
1093   
1094  
1095 /* IsAssignableFrom ************************************************************
1096
1097    Determines whether an object of sub can be safely cast to sup.
1098
1099 *******************************************************************************/
1100
1101 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1102 {
1103         java_lang_Class *csup;
1104         java_lang_Class *csub;
1105
1106         csup = (java_lang_Class *) sup;
1107         csub = (java_lang_Class *) sub;
1108
1109         STATISTICS(jniinvokation());
1110
1111         return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1112 }
1113
1114
1115 /* Throw ***********************************************************************
1116
1117    Causes a java.lang.Throwable object to be thrown.
1118
1119 *******************************************************************************/
1120
1121 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1122 {
1123         java_handle_t *o;
1124
1125         STATISTICS(jniinvokation());
1126
1127         o = (java_handle_t *) obj;
1128
1129         exceptions_set_exception(o);
1130
1131         return JNI_OK;
1132 }
1133
1134
1135 /* ThrowNew ********************************************************************
1136
1137    Constructs an exception object from the specified class with the
1138    message specified by message and causes that exception to be
1139    thrown.
1140
1141 *******************************************************************************/
1142
1143 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1144 {
1145         classinfo     *c;
1146         java_handle_t *o;
1147         java_handle_t *s;
1148
1149         STATISTICS(jniinvokation());
1150
1151         c = LLNI_classinfo_unwrap(clazz);
1152         if (msg == NULL)
1153                 msg = "";
1154         s = javastring_new_from_utf_string(msg);
1155
1156         /* instantiate exception object */
1157
1158         o = native_new_and_init_string(c, s);
1159
1160         if (o == NULL)
1161                 return -1;
1162
1163         exceptions_set_exception(o);
1164
1165         return 0;
1166 }
1167
1168
1169 /* ExceptionOccurred ***********************************************************
1170
1171    Determines if an exception is being thrown. The exception stays
1172    being thrown until either the native code calls ExceptionClear(),
1173    or the Java code handles the exception.
1174
1175 *******************************************************************************/
1176
1177 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1178 {
1179         java_handle_t *o;
1180
1181         TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1182
1183         o = exceptions_get_exception();
1184
1185         return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1186 }
1187
1188
1189 /* ExceptionDescribe ***********************************************************
1190
1191    Prints an exception and a backtrace of the stack to a system
1192    error-reporting channel, such as stderr. This is a convenience
1193    routine provided for debugging.
1194
1195 *******************************************************************************/
1196
1197 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1198 {
1199         java_handle_t *o;
1200         classinfo     *c;
1201         methodinfo    *m;
1202
1203         TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1204
1205         /* Clear exception, because we are probably calling Java code
1206            again. */
1207
1208         o = exceptions_get_and_clear_exception();
1209
1210         if (o != NULL) {
1211                 /* get printStackTrace method from exception class */
1212
1213                 LLNI_class_get(o, c);
1214
1215                 m = class_resolveclassmethod(c,
1216                                                                          utf_printStackTrace,
1217                                                                          utf_void__void,
1218                                                                          NULL,
1219                                                                          true);
1220
1221                 if (m == NULL)
1222                         vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1223
1224                 /* Print the stacktrace. */
1225
1226                 (void) vm_call_method(m, o);
1227         }
1228 }
1229
1230
1231 /* ExceptionClear **************************************************************
1232
1233    Clears any exception that is currently being thrown. If no
1234    exception is currently being thrown, this routine has no effect.
1235
1236 *******************************************************************************/
1237
1238 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1239 {
1240         STATISTICS(jniinvokation());
1241
1242         exceptions_clear_exception();
1243 }
1244
1245
1246 /* FatalError ******************************************************************
1247
1248    Raises a fatal error and does not expect the VM to recover. This
1249    function does not return.
1250
1251 *******************************************************************************/
1252
1253 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1254 {
1255         STATISTICS(jniinvokation());
1256
1257         /* this seems to be the best way */
1258
1259         vm_abort("JNI Fatal error: %s", msg);
1260 }
1261
1262
1263 /* PushLocalFrame **************************************************************
1264
1265    Creates a new local reference frame, in which at least a given
1266    number of local references can be created.
1267
1268 *******************************************************************************/
1269
1270 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1271 {
1272         STATISTICS(jniinvokation());
1273
1274         if (capacity <= 0)
1275                 return -1;
1276
1277         /* add new local reference frame to current table */
1278
1279         if (!localref_frame_push(capacity))
1280                 return -1;
1281
1282         return 0;
1283 }
1284
1285
1286 /* PopLocalFrame ***************************************************************
1287
1288    Pops off the current local reference frame, frees all the local
1289    references, and returns a local reference in the previous local
1290    reference frame for the given result object.
1291
1292 *******************************************************************************/
1293
1294 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1295 {
1296         STATISTICS(jniinvokation());
1297
1298         /* release all current local frames */
1299
1300         localref_frame_pop_all();
1301
1302         /* add local reference and return the value */
1303
1304         return _Jv_JNI_NewLocalRef(env, result);
1305 }
1306
1307
1308 /* DeleteLocalRef **************************************************************
1309
1310    Deletes the local reference pointed to by localRef.
1311
1312 *******************************************************************************/
1313
1314 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1315 {
1316         java_handle_t  *o;
1317
1318         STATISTICS(jniinvokation());
1319
1320         o = (java_handle_t *) localRef;
1321
1322         /* delete the reference */
1323
1324         localref_del(o);
1325 }
1326
1327
1328 /* IsSameObject ****************************************************************
1329
1330    Tests whether two references refer to the same Java object.
1331
1332 *******************************************************************************/
1333
1334 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1335 {
1336         java_handle_t *o1;
1337         java_handle_t *o2;
1338         jboolean       result;
1339
1340         STATISTICS(jniinvokation());
1341
1342         o1 = (java_handle_t *) ref1;
1343         o2 = (java_handle_t *) ref2;
1344
1345         LLNI_CRITICAL_START;
1346
1347         if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1348                 result = JNI_TRUE;
1349         else
1350                 result = JNI_FALSE;
1351
1352         LLNI_CRITICAL_END;
1353
1354         return result;
1355 }
1356
1357
1358 /* NewLocalRef *****************************************************************
1359
1360    Creates a new local reference that refers to the same object as ref.
1361
1362 *******************************************************************************/
1363
1364 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1365 {
1366         java_handle_t *o;
1367         java_handle_t *localref;
1368
1369         STATISTICS(jniinvokation());
1370
1371         if (ref == NULL)
1372                 return NULL;
1373
1374         o = (java_handle_t *) ref;
1375
1376         /* insert the reference */
1377
1378         localref = localref_add(LLNI_DIRECT(o));
1379
1380         return localref;
1381 }
1382
1383
1384 /* EnsureLocalCapacity *********************************************************
1385
1386    Ensures that at least a given number of local references can be
1387    created in the current thread
1388
1389 *******************************************************************************/
1390
1391 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1392 {
1393         localref_table *lrt;
1394
1395         STATISTICS(jniinvokation());
1396
1397         /* get local reference table (thread specific) */
1398
1399         lrt = LOCALREFTABLE;
1400
1401         /* check if capacity elements are available in the local references table */
1402
1403         if ((lrt->used + capacity) > lrt->capacity)
1404                 return _Jv_JNI_PushLocalFrame(env, capacity);
1405
1406         return 0;
1407 }
1408
1409
1410 /* AllocObject *****************************************************************
1411
1412    Allocates a new Java object without invoking any of the
1413    constructors for the object. Returns a reference to the object.
1414
1415 *******************************************************************************/
1416
1417 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1418 {
1419         classinfo     *c;
1420         java_handle_t *o;
1421
1422         STATISTICS(jniinvokation());
1423
1424         c = LLNI_classinfo_unwrap(clazz);
1425
1426         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1427                 exceptions_throw_instantiationexception(c);
1428                 return NULL;
1429         }
1430                 
1431         o = builtin_new(c);
1432
1433         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1434 }
1435
1436
1437 /* NewObject *******************************************************************
1438
1439    Programmers place all arguments that are to be passed to the
1440    constructor immediately following the methodID
1441    argument. NewObject() accepts these arguments and passes them to
1442    the Java method that the programmer wishes to invoke.
1443
1444 *******************************************************************************/
1445
1446 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1447 {
1448         java_handle_t *o;
1449         classinfo     *c;
1450         methodinfo    *m;
1451         va_list        ap;
1452
1453         STATISTICS(jniinvokation());
1454
1455         c = LLNI_classinfo_unwrap(clazz);
1456         m = (methodinfo *) methodID;
1457
1458         /* create object */
1459
1460         o = builtin_new(c);
1461         
1462         if (o == NULL)
1463                 return NULL;
1464
1465         /* call constructor */
1466
1467         va_start(ap, methodID);
1468         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1469         va_end(ap);
1470
1471         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1472 }
1473
1474
1475 /* NewObjectV ******************************************************************
1476
1477    Programmers place all arguments that are to be passed to the
1478    constructor in an args argument of type va_list that immediately
1479    follows the methodID argument. NewObjectV() accepts these
1480    arguments, and, in turn, passes them to the Java method that the
1481    programmer wishes to invoke.
1482
1483 *******************************************************************************/
1484
1485 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1486                                                    va_list args)
1487 {
1488         java_handle_t *o;
1489         classinfo     *c;
1490         methodinfo    *m;
1491
1492         STATISTICS(jniinvokation());
1493
1494         c = LLNI_classinfo_unwrap(clazz);
1495         m = (methodinfo *) methodID;
1496
1497         /* create object */
1498
1499         o = builtin_new(c);
1500         
1501         if (o == NULL)
1502                 return NULL;
1503
1504         /* call constructor */
1505
1506         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1507
1508         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1509 }
1510
1511
1512 /* NewObjectA ***************************************************************** 
1513
1514    Programmers place all arguments that are to be passed to the
1515    constructor in an args array of jvalues that immediately follows
1516    the methodID argument. NewObjectA() accepts the arguments in this
1517    array, and, in turn, passes them to the Java method that the
1518    programmer wishes to invoke.
1519
1520 *******************************************************************************/
1521
1522 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1523                                                    const jvalue *args)
1524 {
1525         java_handle_t *o;
1526         classinfo     *c;
1527         methodinfo    *m;
1528
1529         STATISTICS(jniinvokation());
1530
1531         c = LLNI_classinfo_unwrap(clazz);
1532         m = (methodinfo *) methodID;
1533
1534         /* create object */
1535
1536         o = builtin_new(c);
1537         
1538         if (o == NULL)
1539                 return NULL;
1540
1541         /* call constructor */
1542
1543         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1544
1545         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1546 }
1547
1548
1549 /* GetObjectClass **************************************************************
1550
1551  Returns the class of an object.
1552
1553 *******************************************************************************/
1554
1555 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1556 {
1557         java_handle_t   *o;
1558         classinfo       *c;
1559         java_lang_Class *co;
1560
1561         STATISTICS(jniinvokation());
1562
1563         o = (java_handle_t *) obj;
1564
1565         if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1566                 return NULL;
1567
1568         LLNI_class_get(o, c);
1569
1570         co = LLNI_classinfo_wrap(c);
1571
1572         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1573 }
1574
1575
1576 /* IsInstanceOf ****************************************************************
1577
1578    Tests whether an object is an instance of a class.
1579
1580 *******************************************************************************/
1581
1582 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1583 {
1584         java_lang_Class  *c;
1585         java_lang_Object *o;
1586
1587         STATISTICS(jniinvokation());
1588
1589         c = (java_lang_Class *) clazz;
1590         o = (java_lang_Object *) obj;
1591
1592         return _Jv_java_lang_Class_isInstance(c, o);
1593 }
1594
1595
1596 /* Reflection Support *********************************************************/
1597
1598 /* FromReflectedMethod *********************************************************
1599
1600    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1601    object to a method ID.
1602   
1603 *******************************************************************************/
1604   
1605 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1606 {
1607 #if defined(ENABLE_JAVASE)
1608         java_handle_t *o;
1609         classinfo     *c;
1610         methodinfo    *m;
1611         s4             slot;
1612
1613         STATISTICS(jniinvokation());
1614
1615         o = (java_handle_t *) method;
1616
1617         if (o == NULL)
1618                 return NULL;
1619         
1620         if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1621                 java_lang_reflect_Method *rm;
1622
1623                 rm   = (java_lang_reflect_Method *) method;
1624                 LLNI_field_get_cls(rm, clazz, c);
1625                 LLNI_field_get_val(rm, slot , slot);
1626         }
1627         else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1628                 java_lang_reflect_Constructor *rc;
1629
1630                 rc   = (java_lang_reflect_Constructor *) method;
1631                 LLNI_field_get_cls(rc, clazz, c);
1632                 LLNI_field_get_val(rc, slot , slot);
1633         }
1634         else
1635                 return NULL;
1636
1637         m = &(c->methods[slot]);
1638
1639         return (jmethodID) m;
1640 #else
1641         vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1642
1643         /* keep compiler happy */
1644
1645         return NULL;
1646 #endif
1647 }
1648
1649
1650 /* FromReflectedField **********************************************************
1651
1652    Converts a java.lang.reflect.Field to a field ID.
1653
1654 *******************************************************************************/
1655  
1656 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1657 {
1658 #if defined(ENABLE_JAVASE)
1659         java_lang_reflect_Field *rf;
1660         classinfo               *c;
1661         fieldinfo               *f;
1662         int32_t                  slot;
1663
1664         STATISTICS(jniinvokation());
1665
1666         rf = (java_lang_reflect_Field *) field;
1667
1668         if (rf == NULL)
1669                 return NULL;
1670
1671         LLNI_field_get_cls(rf, clazz, c);
1672         LLNI_field_get_val(rf, slot , slot);
1673         f = &(c->fields[slot]);
1674
1675         return (jfieldID) f;
1676 #else
1677         vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1678
1679         /* keep compiler happy */
1680
1681         return NULL;
1682 #endif
1683 }
1684
1685
1686 /* ToReflectedMethod ***********************************************************
1687
1688    Converts a method ID derived from cls to an instance of the
1689    java.lang.reflect.Method class or to an instance of the
1690    java.lang.reflect.Constructor class.
1691
1692 *******************************************************************************/
1693
1694 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1695                                                                   jboolean isStatic)
1696 {
1697 #if defined(ENABLE_JAVASE)
1698         methodinfo                    *m;
1699         java_lang_reflect_Constructor *rc;
1700         java_lang_reflect_Method      *rm;
1701
1702         TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1703
1704         m = (methodinfo *) methodID;
1705
1706         /* HotSpot does the same assert. */
1707
1708         assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1709
1710         if (m->name == utf_init) {
1711                 rc = reflect_constructor_new(m);
1712
1713                 return (jobject) rc;
1714         }
1715         else {
1716                 rm = reflect_method_new(m);
1717
1718                 return (jobject) rm;
1719         }
1720 #else
1721         vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1722
1723         /* keep compiler happy */
1724
1725         return NULL;
1726 #endif
1727 }
1728
1729
1730 /* ToReflectedField ************************************************************
1731
1732    Converts a field ID derived from cls to an instance of the
1733    java.lang.reflect.Field class.
1734
1735 *******************************************************************************/
1736
1737 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1738                                                                  jboolean isStatic)
1739 {
1740         STATISTICS(jniinvokation());
1741
1742         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1743
1744         return NULL;
1745 }
1746
1747
1748 /* Calling Instance Methods ***************************************************/
1749
1750 /* GetMethodID *****************************************************************
1751
1752    Returns the method ID for an instance (nonstatic) method of a class
1753    or interface. The method may be defined in one of the clazz's
1754    superclasses and inherited by clazz. The method is determined by
1755    its name and signature.
1756
1757    GetMethodID() causes an uninitialized class to be initialized.
1758
1759 *******************************************************************************/
1760
1761 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1762                                                           const char *sig)
1763 {
1764         classinfo  *c;
1765         utf        *uname;
1766         utf        *udesc;
1767         methodinfo *m;
1768
1769         STATISTICS(jniinvokation());
1770
1771         c = LLNI_classinfo_unwrap(clazz);
1772
1773         if (c == NULL)
1774                 return NULL;
1775
1776         if (!(c->state & CLASS_INITIALIZED))
1777                 if (!initialize_class(c))
1778                         return NULL;
1779
1780         /* try to get the method of the class or one of it's superclasses */
1781
1782         uname = utf_new_char((char *) name);
1783         udesc = utf_new_char((char *) sig);
1784
1785         m = class_resolvemethod(c, uname, udesc);
1786
1787         if ((m == NULL) || (m->flags & ACC_STATIC)) {
1788                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1789
1790                 return NULL;
1791         }
1792
1793         return (jmethodID) m;
1794 }
1795
1796
1797 /* JNI-functions for calling instance methods *********************************/
1798
1799 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
1800 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
1801                                                                 jmethodID methodID, ...)    \
1802 {                                                           \
1803         java_handle_t *o;                                       \
1804         methodinfo    *m;                                       \
1805         va_list        ap;                                      \
1806         type           ret;                                     \
1807                                                             \
1808         o = (java_handle_t *) obj;                              \
1809         m = (methodinfo *) methodID;                            \
1810                                                             \
1811         va_start(ap, methodID);                                 \
1812         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1813         va_end(ap);                                             \
1814                                                             \
1815         return ret;                                             \
1816 }
1817
1818 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1819 JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
1820 JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
1821 JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
1822 JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
1823 JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
1824 JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
1825 JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
1826
1827
1828 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
1829 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
1830                                                                  jmethodID methodID, va_list args) \
1831 {                                                                  \
1832         java_handle_t *o;                                              \
1833         methodinfo    *m;                                              \
1834         type           ret;                                            \
1835                                                                    \
1836         o = (java_handle_t *) obj;                                     \
1837         m = (methodinfo *) methodID;                                   \
1838                                                                    \
1839         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args);      \
1840                                                                    \
1841         return ret;                                                    \
1842 }
1843
1844 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1845 JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
1846 JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
1847 JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
1848 JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
1849 JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
1850 JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
1851 JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
1852
1853
1854 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
1855 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
1856                                                                  jmethodID methodID,           \
1857                                                                  const jvalue *args)           \
1858 {                                                              \
1859         java_handle_t *o;                                          \
1860         methodinfo    *m;                                          \
1861         type           ret;                                        \
1862                                                                \
1863         o = (java_handle_t *) obj;                                 \
1864         m = (methodinfo *) methodID;                               \
1865                                                                \
1866         ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1867                                                                \
1868         return ret;                                                \
1869 }
1870
1871 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1872 JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
1873 JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
1874 JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
1875 JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
1876 JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
1877 JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
1878 JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
1879
1880
1881 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1882                                                                  ...)
1883 {
1884         java_handle_t *o;
1885         methodinfo    *m;
1886         java_handle_t *ret;
1887         va_list        ap;
1888
1889         o = (java_handle_t *) obj;
1890         m = (methodinfo *) methodID;
1891
1892         va_start(ap, methodID);
1893         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1894         va_end(ap);
1895
1896         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1897 }
1898
1899
1900 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1901                                                                   va_list args)
1902 {
1903         java_handle_t *o;
1904         methodinfo    *m;
1905         java_handle_t *ret;
1906
1907         o = (java_handle_t *) obj;
1908         m = (methodinfo *) methodID;
1909
1910         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1911
1912         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1913 }
1914
1915
1916 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1917                                                                   const jvalue *args)
1918 {
1919         java_handle_t *o;
1920         methodinfo    *m;
1921         java_handle_t *ret;
1922
1923         o = (java_handle_t *) obj;
1924         m = (methodinfo *) methodID;
1925
1926         ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1927
1928         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1929 }
1930
1931
1932
1933 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1934 {
1935         java_handle_t *o;
1936         methodinfo    *m;
1937         va_list        ap;
1938
1939         o = (java_handle_t *) obj;
1940         m = (methodinfo *) methodID;
1941
1942         va_start(ap, methodID);
1943         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1944         va_end(ap);
1945 }
1946
1947
1948 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1949                                                          va_list args)
1950 {
1951         java_handle_t *o;
1952         methodinfo    *m;
1953
1954         o = (java_handle_t *) obj;
1955         m = (methodinfo *) methodID;
1956
1957         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1958 }
1959
1960
1961 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1962                                                          const jvalue *args)
1963 {
1964         java_handle_t *o;
1965         methodinfo    *m;
1966
1967         o = (java_handle_t *) obj;
1968         m = (methodinfo *) methodID;
1969
1970         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1971 }
1972
1973
1974
1975 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
1976 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
1977                                                                                   jclass clazz, jmethodID methodID, \
1978                                                                                   ...)                              \
1979 {                                                                           \
1980         java_handle_t *o;                                                       \
1981         classinfo     *c;                                                       \
1982         methodinfo    *m;                                                       \
1983         va_list        ap;                                                      \
1984         type           ret;                                                     \
1985                                                                             \
1986         o = (java_handle_t *) obj;                                              \
1987         c = LLNI_classinfo_unwrap(clazz);                                       \
1988         m = (methodinfo *) methodID;                                            \
1989                                                                             \
1990         va_start(ap, methodID);                                                 \
1991         ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
1992         va_end(ap);                                                             \
1993                                                                             \
1994         return ret;                                                             \
1995 }
1996
1997 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1998 JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
1999 JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
2000 JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
2001 JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
2002 JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
2003 JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
2004 JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
2005
2006
2007 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
2008 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
2009                                                                                    jclass clazz, jmethodID methodID, \
2010                                                                                    va_list args)                     \
2011 {                                                                            \
2012         java_handle_t *o;                                                        \
2013         classinfo     *c;                                                        \
2014         methodinfo    *m;                                                        \
2015         type           ret;                                                      \
2016                                                                              \
2017         o = (java_handle_t *) obj;                                               \
2018         c = LLNI_classinfo_unwrap(clazz);                                        \
2019         m = (methodinfo *) methodID;                                             \
2020                                                                              \
2021         ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
2022                                                                              \
2023         return ret;                                                              \
2024 }
2025
2026 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
2032 JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
2033 JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
2034
2035
2036 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
2037 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
2038                                                                                    jclass clazz, jmethodID methodID, \
2039                                                                                    const jvalue *args)               \
2040 {                                                                            \
2041         log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
2042                                                                              \
2043         return 0;                                                                \
2044 }
2045
2046 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2047 JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
2048 JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
2049 JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
2050 JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
2051 JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
2052 JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
2053 JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
2054
2055 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2056                                                                                    jclass clazz, jmethodID methodID,
2057                                                                                    ...)
2058 {
2059         java_handle_t *o;
2060         classinfo     *c;
2061         methodinfo    *m;
2062         java_handle_t *r;
2063         va_list        ap;
2064
2065         o = (java_handle_t *) obj;
2066         c = LLNI_classinfo_unwrap(clazz);
2067         m = (methodinfo *) methodID;
2068
2069         va_start(ap, methodID);
2070         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2071         va_end(ap);
2072
2073         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2074 }
2075
2076
2077 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2078                                                                                         jclass clazz, jmethodID methodID,
2079                                                                                         va_list args)
2080 {
2081         java_handle_t *o;
2082         classinfo     *c;
2083         methodinfo    *m;
2084         java_handle_t *r;
2085
2086         o = (java_handle_t *) obj;
2087         c = LLNI_classinfo_unwrap(clazz);
2088         m = (methodinfo *) methodID;
2089
2090         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2091
2092         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2093 }
2094
2095
2096 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2097                                                                                         jclass clazz, jmethodID methodID,
2098                                                                                         const jvalue *args)
2099 {
2100         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2101
2102         return _Jv_JNI_NewLocalRef(env, NULL);
2103 }
2104
2105
2106 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2107                                                                           jmethodID methodID, ...)
2108 {
2109         java_handle_t *o;
2110         classinfo     *c;
2111         methodinfo    *m;
2112         va_list        ap;
2113
2114         o = (java_handle_t *) obj;
2115         c = LLNI_classinfo_unwrap(clazz);
2116         m = (methodinfo *) methodID;
2117
2118         va_start(ap, methodID);
2119         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2120         va_end(ap);
2121 }
2122
2123
2124 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2125                                                                            jmethodID methodID, va_list args)
2126 {
2127         java_handle_t *o;
2128         classinfo     *c;
2129         methodinfo    *m;
2130
2131         o = (java_handle_t *) obj;
2132         c = LLNI_classinfo_unwrap(clazz);
2133         m = (methodinfo *) methodID;
2134
2135         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2136 }
2137
2138
2139 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2140                                                                            jmethodID methodID, const jvalue * args)
2141 {       
2142         java_handle_t *o;
2143         classinfo     *c;
2144         methodinfo    *m;
2145
2146         o = (java_handle_t *) obj;
2147         c = LLNI_classinfo_unwrap(clazz);
2148         m = (methodinfo *) methodID;
2149
2150         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2151 }
2152
2153
2154 /* Accessing Fields of Objects ************************************************/
2155
2156 /* GetFieldID ******************************************************************
2157
2158    Returns the field ID for an instance (nonstatic) field of a
2159    class. The field is specified by its name and signature. The
2160    Get<type>Field and Set<type>Field families of accessor functions
2161    use field IDs to retrieve object fields.
2162
2163 *******************************************************************************/
2164
2165 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2166                                                         const char *sig)
2167 {
2168         classinfo *c;
2169         fieldinfo *f;
2170         utf       *uname;
2171         utf       *udesc;
2172
2173         STATISTICS(jniinvokation());
2174
2175         c = LLNI_classinfo_unwrap(clazz);
2176
2177         /* XXX NPE check? */
2178
2179         uname = utf_new_char((char *) name);
2180         udesc = utf_new_char((char *) sig);
2181
2182         f = class_findfield(c, uname, udesc); 
2183         
2184         if (f == NULL)
2185                 exceptions_throw_nosuchfielderror(c, uname);  
2186
2187         return (jfieldID) f;
2188 }
2189
2190
2191 /* Get<type>Field Routines *****************************************************
2192
2193    This family of accessor routines returns the value of an instance
2194    (nonstatic) field of an object. The field to access is specified by
2195    a field ID obtained by calling GetFieldID().
2196
2197 *******************************************************************************/
2198
2199 #define JNI_GET_FIELD(name, type, intern)                                 \
2200 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2201 {                                                                         \
2202         intern ret;                                                           \
2203                                                                           \
2204         STATISTICS(jniinvokation());                                          \
2205                                                                           \
2206         ret = GET_FIELD(obj, intern, fieldID);                                \
2207                                                                           \
2208         return (type) ret;                                                    \
2209 }
2210
2211 JNI_GET_FIELD(Boolean, jboolean, s4)
2212 JNI_GET_FIELD(Byte,    jbyte,    s4)
2213 JNI_GET_FIELD(Char,    jchar,    s4)
2214 JNI_GET_FIELD(Short,   jshort,   s4)
2215 JNI_GET_FIELD(Int,     jint,     s4)
2216 JNI_GET_FIELD(Long,    jlong,    s8)
2217 JNI_GET_FIELD(Float,   jfloat,   float)
2218 JNI_GET_FIELD(Double,  jdouble,  double)
2219
2220
2221 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2222 {
2223         java_handle_t *o;
2224
2225         TRACEJNICALLS("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID);
2226
2227         LLNI_CRITICAL_START;
2228
2229         o = LLNI_WRAP(GET_FIELD(obj, java_handle_t*, fieldID));
2230
2231         LLNI_CRITICAL_END;
2232
2233         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2234 }
2235
2236
2237 /* Set<type>Field Routines *****************************************************
2238
2239    This family of accessor routines sets the value of an instance
2240    (nonstatic) field of an object. The field to access is specified by
2241    a field ID obtained by calling GetFieldID().
2242
2243 *******************************************************************************/
2244
2245 #define JNI_SET_FIELD(name, type, intern)                                 \
2246 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2247                                                           type value)                                 \
2248 {                                                                         \
2249         STATISTICS(jniinvokation());                                          \
2250                                                                           \
2251         SET_FIELD(obj, intern, fieldID, value);                               \
2252 }
2253
2254 JNI_SET_FIELD(Boolean, jboolean, s4)
2255 JNI_SET_FIELD(Byte,    jbyte,    s4)
2256 JNI_SET_FIELD(Char,    jchar,    s4)
2257 JNI_SET_FIELD(Short,   jshort,   s4)
2258 JNI_SET_FIELD(Int,     jint,     s4)
2259 JNI_SET_FIELD(Long,    jlong,    s8)
2260 JNI_SET_FIELD(Float,   jfloat,   float)
2261 JNI_SET_FIELD(Double,  jdouble,  double)
2262
2263
2264 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2265                                                         jobject value)
2266 {
2267         TRACEJNICALLS("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value);
2268
2269         LLNI_CRITICAL_START;
2270
2271         SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP(value));
2272
2273         LLNI_CRITICAL_END;
2274 }
2275
2276
2277 /* Calling Static Methods *****************************************************/
2278
2279 /* GetStaticMethodID ***********************************************************
2280
2281    Returns the method ID for a static method of a class. The method is
2282    specified by its name and signature.
2283
2284    GetStaticMethodID() causes an uninitialized class to be
2285    initialized.
2286
2287 *******************************************************************************/
2288
2289 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2290                                                                         const char *sig)
2291 {
2292         classinfo  *c;
2293         utf        *uname;
2294         utf        *udesc;
2295         methodinfo *m;
2296
2297         TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2298
2299         c = LLNI_classinfo_unwrap(clazz);
2300
2301         if (c == NULL)
2302                 return NULL;
2303
2304         if (!(c->state & CLASS_INITIALIZED))
2305                 if (!initialize_class(c))
2306                         return NULL;
2307
2308         /* try to get the static method of the class */
2309
2310         uname = utf_new_char((char *) name);
2311         udesc = utf_new_char((char *) sig);
2312
2313         m = class_resolvemethod(c, uname, udesc);
2314
2315         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2316                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2317
2318                 return NULL;
2319         }
2320
2321         return (jmethodID) m;
2322 }
2323
2324
2325 #define JNI_CALL_STATIC_METHOD(name, type, intern)               \
2326 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2327                                                                           jmethodID methodID, ...)   \
2328 {                                                                \
2329         methodinfo *m;                                               \
2330         va_list     ap;                                              \
2331         type        res;                                             \
2332                                                                  \
2333         m = (methodinfo *) methodID;                                 \
2334                                                                  \
2335         va_start(ap, methodID);                                      \
2336         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
2337         va_end(ap);                                                  \
2338                                                                  \
2339         return res;                                                  \
2340 }
2341
2342 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2343 JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
2344 JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
2345 JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
2346 JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
2347 JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
2348 JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
2349 JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
2350
2351
2352 #define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
2353 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
2354                                                                            jmethodID methodID, va_list args) \
2355 {                                                                        \
2356         methodinfo *m;                                                       \
2357         type        res;                                                     \
2358                                                                          \
2359         m = (methodinfo *) methodID;                                         \
2360                                                                          \
2361         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
2362                                                                          \
2363         return res;                                                          \
2364 }
2365
2366 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2367 JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
2368 JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
2369 JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
2370 JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
2371 JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
2372 JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
2373 JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
2374
2375
2376 #define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
2377 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
2378                                                                            jmethodID methodID, const jvalue *args) \
2379 {                                                                              \
2380         methodinfo *m;                                                             \
2381         type        res;                                                           \
2382                                                                                \
2383         m = (methodinfo *) methodID;                                               \
2384                                                                                \
2385         res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
2386                                                                                \
2387         return res;                                                                \
2388 }
2389
2390 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2391 JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
2392 JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
2393 JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
2394 JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
2395 JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
2396 JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
2397 JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
2398
2399
2400 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2401                                                                            jmethodID methodID, ...)
2402 {
2403         methodinfo    *m;
2404         java_handle_t *o;
2405         va_list        ap;
2406
2407         m = (methodinfo *) methodID;
2408
2409         va_start(ap, methodID);
2410         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2411         va_end(ap);
2412
2413         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2414 }
2415
2416
2417 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2418                                                                                 jmethodID methodID, va_list args)
2419 {
2420         methodinfo    *m;
2421         java_handle_t *o;
2422
2423         m = (methodinfo *) methodID;
2424
2425         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2426
2427         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2428 }
2429
2430
2431 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2432                                                                                 jmethodID methodID, const jvalue *args)
2433 {
2434         methodinfo    *m;
2435         java_handle_t *o;
2436
2437         m = (methodinfo *) methodID;
2438
2439         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2440
2441         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2442 }
2443
2444
2445 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2446                                                                   jmethodID methodID, ...)
2447 {
2448         methodinfo *m;
2449         va_list     ap;
2450
2451         m = (methodinfo *) methodID;
2452
2453         va_start(ap, methodID);
2454         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2455         va_end(ap);
2456 }
2457
2458
2459 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2460                                                                    jmethodID methodID, va_list args)
2461 {
2462         methodinfo *m;
2463
2464         m = (methodinfo *) methodID;
2465
2466         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2467 }
2468
2469
2470 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2471                                                                    jmethodID methodID, const jvalue * args)
2472 {
2473         methodinfo *m;
2474
2475         m = (methodinfo *) methodID;
2476
2477         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2478 }
2479
2480
2481 /* Accessing Static Fields ****************************************************/
2482
2483 /* GetStaticFieldID ************************************************************
2484
2485    Returns the field ID for a static field of a class. The field is
2486    specified by its name and signature. The GetStatic<type>Field and
2487    SetStatic<type>Field families of accessor functions use field IDs
2488    to retrieve static fields.
2489
2490 *******************************************************************************/
2491
2492 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2493                                                                   const char *sig)
2494 {
2495         classinfo *c;
2496         fieldinfo *f;
2497         utf       *uname;
2498         utf       *usig;
2499
2500         STATISTICS(jniinvokation());
2501
2502         c = LLNI_classinfo_unwrap(clazz);
2503
2504         uname = utf_new_char((char *) name);
2505         usig  = utf_new_char((char *) sig);
2506
2507         f = class_findfield(c, uname, usig);
2508         
2509         if (f == NULL)
2510                 exceptions_throw_nosuchfielderror(c, uname);
2511
2512         return (jfieldID) f;
2513 }
2514
2515
2516 /* GetStatic<type>Field ********************************************************
2517
2518    This family of accessor routines returns the value of a static
2519    field of an object.
2520
2521 *******************************************************************************/
2522
2523 #define JNI_GET_STATIC_FIELD(name, type, field)                \
2524 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2525                                                                         jfieldID fieldID)          \
2526 {                                                              \
2527         classinfo *c;                                              \
2528         fieldinfo *f;                                              \
2529                                                                \
2530         STATISTICS(jniinvokation());                               \
2531                                                                \
2532         c = LLNI_classinfo_unwrap(clazz);                          \
2533         f = (fieldinfo *) fieldID;                                 \
2534                                                                \
2535         if (!(c->state & CLASS_INITIALIZED))                       \
2536                 if (!initialize_class(c))                              \
2537                         return 0;                                          \
2538                                                                \
2539         return f->value->field;                                    \
2540 }
2541
2542 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2543 JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
2544 JNI_GET_STATIC_FIELD(Char,    jchar,    i)
2545 JNI_GET_STATIC_FIELD(Short,   jshort,   i)
2546 JNI_GET_STATIC_FIELD(Int,     jint,     i)
2547 JNI_GET_STATIC_FIELD(Long,    jlong,    l)
2548 JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
2549 JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
2550
2551
2552 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2553                                                                          jfieldID fieldID)
2554 {
2555         classinfo *c;
2556         fieldinfo *f;
2557
2558         STATISTICS(jniinvokation());
2559
2560         c = LLNI_classinfo_unwrap(clazz);
2561         f = (fieldinfo *) fieldID;
2562
2563         if (!(c->state & CLASS_INITIALIZED))
2564                 if (!initialize_class(c))
2565                         return NULL;
2566
2567         return _Jv_JNI_NewLocalRef(env, f->value->a);
2568 }
2569
2570
2571 /*  SetStatic<type>Field *******************************************************
2572
2573         This family of accessor routines sets the value of a static field
2574         of an object.
2575
2576 *******************************************************************************/
2577
2578 #define JNI_SET_STATIC_FIELD(name, type, field)                \
2579 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2580                                                                         jfieldID fieldID,          \
2581                                                                         type value)                \
2582 {                                                              \
2583         classinfo *c;                                              \
2584         fieldinfo *f;                                              \
2585                                                                \
2586         STATISTICS(jniinvokation());                               \
2587                                                                \
2588         c = LLNI_classinfo_unwrap(clazz);                          \
2589         f = (fieldinfo *) fieldID;                                 \
2590                                                                \
2591         if (!(c->state & CLASS_INITIALIZED))                       \
2592                 if (!initialize_class(c))                              \
2593                         return;                                            \
2594                                                                \
2595         f->value->field = value;                                   \
2596 }
2597
2598 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2599 JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
2600 JNI_SET_STATIC_FIELD(Char,    jchar,    i)
2601 JNI_SET_STATIC_FIELD(Short,   jshort,   i)
2602 JNI_SET_STATIC_FIELD(Int,     jint,     i)
2603 JNI_SET_STATIC_FIELD(Long,    jlong,    l)
2604 JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
2605 JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
2606
2607
2608 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2609                                                                   jobject value)
2610 {
2611         classinfo *c;
2612         fieldinfo *f;
2613
2614         STATISTICS(jniinvokation());
2615
2616         c = LLNI_classinfo_unwrap(clazz);
2617         f = (fieldinfo *) fieldID;
2618
2619         if (!(c->state & CLASS_INITIALIZED))
2620                 if (!initialize_class(c))
2621                         return;
2622
2623         f->value->a = value;
2624 }
2625
2626
2627 /* String Operations **********************************************************/
2628
2629 /* NewString *******************************************************************
2630
2631    Create new java.lang.String object from an array of Unicode
2632    characters.
2633
2634 *******************************************************************************/
2635
2636 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2637 {
2638         java_lang_String        *s;
2639         java_handle_chararray_t *a;
2640         u4                       i;
2641
2642         STATISTICS(jniinvokation());
2643         
2644         s = (java_lang_String *) builtin_new(class_java_lang_String);
2645         a = builtin_newarray_char(len);
2646
2647         /* javastring or characterarray could not be created */
2648         if ((a == NULL) || (s == NULL))
2649                 return NULL;
2650
2651         /* copy text */
2652         for (i = 0; i < len; i++)
2653                 LLNI_array_direct(a, i) = buf[i];
2654
2655         LLNI_field_set_ref(s, value , a);
2656         LLNI_field_set_val(s, offset, 0);
2657         LLNI_field_set_val(s, count , len);
2658
2659         return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2660 }
2661
2662
2663 static jchar emptyStringJ[]={0,0};
2664
2665 /* GetStringLength *************************************************************
2666
2667    Returns the length (the count of Unicode characters) of a Java
2668    string.
2669
2670 *******************************************************************************/
2671
2672 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2673 {
2674         java_lang_String *s;
2675         jsize             len;
2676
2677         TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2678
2679         s = (java_lang_String *) str;
2680
2681         LLNI_field_get_val(s, count, len);
2682
2683         return len;
2684 }
2685
2686
2687 /********************  convertes javastring to u2-array ****************************/
2688         
2689 u2 *javastring_tou2(jstring so) 
2690 {
2691         java_lang_String        *s;
2692         java_handle_chararray_t *a;
2693         u2                      *stringbuffer;
2694         u4                       i;
2695         int32_t                  count;
2696         int32_t                  offset;
2697
2698         STATISTICS(jniinvokation());
2699         
2700         s = (java_lang_String *) so;
2701
2702         if (!s)
2703                 return NULL;
2704
2705         LLNI_field_get_ref(s, value, a);
2706
2707         if (!a)
2708                 return NULL;
2709
2710         LLNI_field_get_val(s, count, count);
2711         LLNI_field_get_val(s, offset, offset);
2712
2713         /* allocate memory */
2714
2715         stringbuffer = MNEW(u2, count + 1);
2716
2717         /* copy text */
2718
2719         for (i = 0; i < count; i++)
2720                 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2721         
2722         /* terminate string */
2723
2724         stringbuffer[i] = '\0';
2725
2726         return stringbuffer;
2727 }
2728
2729
2730 /* GetStringChars **************************************************************
2731
2732    Returns a pointer to the array of Unicode characters of the
2733    string. This pointer is valid until ReleaseStringChars() is called.
2734
2735 *******************************************************************************/
2736
2737 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2738 {       
2739         jchar *jc;
2740
2741         STATISTICS(jniinvokation());
2742
2743         jc = javastring_tou2(str);
2744
2745         if (jc) {
2746                 if (isCopy)
2747                         *isCopy = JNI_TRUE;
2748
2749                 return jc;
2750         }
2751
2752         if (isCopy)
2753                 *isCopy = JNI_TRUE;
2754
2755         return emptyStringJ;
2756 }
2757
2758
2759 /* ReleaseStringChars **********************************************************
2760
2761    Informs the VM that the native code no longer needs access to
2762    chars. The chars argument is a pointer obtained from string using
2763    GetStringChars().
2764
2765 *******************************************************************************/
2766
2767 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2768 {
2769         java_lang_String *s;
2770
2771         STATISTICS(jniinvokation());
2772
2773         if (chars == emptyStringJ)
2774                 return;
2775
2776         s = (java_lang_String *) str;
2777
2778         MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2779 }
2780
2781
2782 /* NewStringUTF ****************************************************************
2783
2784    Constructs a new java.lang.String object from an array of UTF-8
2785    characters.
2786
2787 *******************************************************************************/
2788
2789 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2790 {
2791         java_lang_String *s;
2792
2793         TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2794
2795         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2796
2797     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2798 }
2799
2800
2801 /****************** returns the utf8 length in bytes of a string *******************/
2802
2803 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2804 {   
2805         java_lang_String *s;
2806         s4                length;
2807
2808         TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2809
2810         s = (java_lang_String *) string;
2811
2812         length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2813
2814         return length;
2815 }
2816
2817
2818 /* GetStringUTFChars ***********************************************************
2819
2820    Returns a pointer to an array of UTF-8 characters of the
2821    string. This array is valid until it is released by
2822    ReleaseStringUTFChars().
2823
2824 *******************************************************************************/
2825
2826 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2827                                                                           jboolean *isCopy)
2828 {
2829         utf *u;
2830
2831         STATISTICS(jniinvokation());
2832
2833         if (string == NULL)
2834                 return "";
2835
2836         if (isCopy)
2837                 *isCopy = JNI_TRUE;
2838         
2839         u = javastring_toutf((java_handle_t *) string, false);
2840
2841         if (u != NULL)
2842                 return u->text;
2843
2844         return "";
2845 }
2846
2847
2848 /* ReleaseStringUTFChars *******************************************************
2849
2850    Informs the VM that the native code no longer needs access to
2851    utf. The utf argument is a pointer derived from string using
2852    GetStringUTFChars().
2853
2854 *******************************************************************************/
2855
2856 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2857 {
2858         STATISTICS(jniinvokation());
2859
2860     /* XXX we don't release utf chars right now, perhaps that should be done 
2861            later. Since there is always one reference the garbage collector will
2862            never get them */
2863 }
2864
2865
2866 /* Array Operations ***********************************************************/
2867
2868 /* GetArrayLength **************************************************************
2869
2870    Returns the number of elements in the array.
2871
2872 *******************************************************************************/
2873
2874 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2875 {
2876         java_handle_t *a;
2877         jsize          size;
2878
2879         STATISTICS(jniinvokation());
2880
2881         a = (java_handle_t *) array;
2882
2883         size = LLNI_array_size(a);
2884
2885         return size;
2886 }
2887
2888
2889 /* NewObjectArray **************************************************************
2890
2891    Constructs a new array holding objects in class elementClass. All
2892    elements are initially set to initialElement.
2893
2894 *******************************************************************************/
2895
2896 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2897                                                                         jclass elementClass, jobject initialElement)
2898 {
2899         classinfo                 *c;
2900         java_handle_t             *o;
2901         java_handle_objectarray_t *oa;
2902         s4                         i;
2903
2904         STATISTICS(jniinvokation());
2905
2906         c = LLNI_classinfo_unwrap(elementClass);
2907         o = (java_handle_t *) initialElement;
2908
2909         if (length < 0) {
2910                 exceptions_throw_negativearraysizeexception();
2911                 return NULL;
2912         }
2913
2914     oa = builtin_anewarray(length, c);
2915
2916         if (oa == NULL)
2917                 return NULL;
2918
2919         /* set all elements to initialElement */
2920
2921         for (i = 0; i < length; i++)
2922                 LLNI_objectarray_element_set(oa, i, o);
2923
2924         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2925 }
2926
2927
2928 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2929                                                                           jsize index)
2930 {
2931         java_handle_objectarray_t *oa;
2932         java_handle_t             *o;
2933
2934         STATISTICS(jniinvokation());
2935
2936         oa = (java_handle_objectarray_t *) array;
2937
2938         if (index >= LLNI_array_size(oa)) {
2939                 exceptions_throw_arrayindexoutofboundsexception();
2940                 return NULL;
2941         }
2942
2943         LLNI_objectarray_element_get(oa, index, o);
2944
2945         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2946 }
2947
2948
2949 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2950                                                                    jsize index, jobject val)
2951 {
2952         java_handle_objectarray_t *oa;
2953         java_handle_t             *o;
2954
2955         STATISTICS(jniinvokation());
2956
2957         oa = (java_handle_objectarray_t *) array;
2958         o  = (java_handle_t *) val;
2959
2960         if (index >= LLNI_array_size(oa)) {
2961                 exceptions_throw_arrayindexoutofboundsexception();
2962                 return;
2963         }
2964
2965         /* check if the class of value is a subclass of the element class
2966            of the array */
2967
2968         if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2969                 return;
2970
2971         LLNI_objectarray_element_set(oa, index, o);
2972 }
2973
2974
2975 #define JNI_NEW_ARRAY(name, type, intern)                \
2976 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
2977 {                                                        \
2978         java_handle_##intern##array_t *a;                    \
2979                                                          \
2980         STATISTICS(jniinvokation());                         \
2981                                                          \
2982         if (len < 0) {                                       \
2983                 exceptions_throw_negativearraysizeexception();   \
2984                 return NULL;                                     \
2985         }                                                    \
2986                                                          \
2987         a = builtin_newarray_##intern(len);                  \
2988                                                          \
2989         return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2990 }
2991
2992 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2993 JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
2994 JNI_NEW_ARRAY(Char,    jcharArray,    char)
2995 JNI_NEW_ARRAY(Short,   jshortArray,   byte)
2996 JNI_NEW_ARRAY(Int,     jintArray,     int)
2997 JNI_NEW_ARRAY(Long,    jlongArray,    long)
2998 JNI_NEW_ARRAY(Float,   jfloatArray,   float)
2999 JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
3000
3001
3002 /* Get<PrimitiveType>ArrayElements *********************************************
3003
3004    A family of functions that returns the body of the primitive array.
3005
3006 *******************************************************************************/
3007
3008 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
3009 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
3010                                                                                  jboolean *isCopy)             \
3011 {                                                                      \
3012         java_handle_##intern##array_t *a;                                  \
3013                                                                        \
3014         STATISTICS(jniinvokation());                                       \
3015                                                                        \
3016         a = (java_handle_##intern##array_t *) array;                       \
3017                                                                        \
3018         if (isCopy)                                                        \
3019                 *isCopy = JNI_FALSE;                                           \
3020                                                                        \
3021         return LLNI_array_data(a);                                         \
3022 }
3023
3024 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
3025 JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
3026 JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
3027 JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
3028 JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
3029 JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
3030 JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
3031 JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
3032
3033
3034 /* Release<PrimitiveType>ArrayElements *****************************************
3035
3036    A family of functions that informs the VM that the native code no
3037    longer needs access to elems. The elems argument is a pointer
3038    derived from array using the corresponding
3039    Get<PrimitiveType>ArrayElements() function. If necessary, this
3040    function copies back all changes made to elems to the original
3041    array.
3042
3043 *******************************************************************************/
3044
3045 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
3046 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
3047                                                                                   type *elems, jint mode)          \
3048 {                                                                          \
3049         java_handle_##intern##array_t *a;                                      \
3050                                                                            \
3051         STATISTICS(jniinvokation());                                           \
3052                                                                            \
3053         a = (java_handle_##intern##array_t *) array;                           \
3054                                                                            \
3055         if (elems != LLNI_array_data(a)) {                                     \
3056                 switch (mode) {                                                    \
3057                 case JNI_COMMIT:                                                   \
3058                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3059                         break;                                                         \
3060                 case 0:                                                            \
3061                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3062                         /* XXX TWISTI how should it be freed? */                       \
3063                         break;                                                         \
3064                 case JNI_ABORT:                                                    \
3065                         /* XXX TWISTI how should it be freed? */                       \
3066                         break;                                                         \
3067                 }                                                                  \
3068         }                                                                      \
3069 }
3070
3071 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3072 JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
3073 JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
3074 JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
3075 JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
3076 JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
3077 JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
3078 JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
3079
3080
3081 /*  Get<PrimitiveType>ArrayRegion **********************************************
3082
3083         A family of functions that copies a region of a primitive array
3084         into a buffer.
3085
3086 *******************************************************************************/
3087
3088 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
3089 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
3090                                                                         jsize start, jsize len, type *buf)  \
3091 {                                                                       \
3092         java_handle_##intern##array_t *a;                                   \
3093                                                                         \
3094         STATISTICS(jniinvokation());                                        \
3095                                                                         \
3096         a = (java_handle_##intern##array_t *) array;                        \
3097                                                                         \
3098         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3099                 exceptions_throw_arrayindexoutofboundsexception();              \
3100         else                                                                \
3101                 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
3102 }
3103
3104 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3105 JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3106 JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
3107 JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
3108 JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
3109 JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
3110 JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
3111 JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
3112
3113
3114 /*  Set<PrimitiveType>ArrayRegion **********************************************
3115
3116         A family of functions that copies back a region of a primitive
3117         array from a buffer.
3118
3119 *******************************************************************************/
3120
3121 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
3122 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
3123                                                                         jsize start, jsize len, const type *buf) \
3124 {                                                                            \
3125         java_handle_##intern##array_t *a;                                        \
3126                                                                              \
3127         STATISTICS(jniinvokation());                                             \
3128                                                                              \
3129         a = (java_handle_##intern##array_t *) array;                             \
3130                                                                              \
3131         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
3132                 exceptions_throw_arrayindexoutofboundsexception();                   \
3133         else                                                                     \
3134                 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
3135 }
3136
3137 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3138 JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3139 JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
3140 JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
3141 JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
3142 JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
3143 JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
3144 JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
3145
3146
3147 /* Registering Native Methods *************************************************/
3148
3149 /* RegisterNatives *************************************************************
3150
3151    Registers native methods with the class specified by the clazz
3152    argument. The methods parameter specifies an array of
3153    JNINativeMethod structures that contain the names, signatures, and
3154    function pointers of the native methods. The nMethods parameter
3155    specifies the number of native methods in the array.
3156
3157 *******************************************************************************/
3158
3159 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3160                                                          const JNINativeMethod *methods, jint nMethods)
3161 {
3162         classinfo *c;
3163
3164         STATISTICS(jniinvokation());
3165
3166         c = LLNI_classinfo_unwrap(clazz);
3167
3168         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3169         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
3170         */
3171
3172         native_method_register(c->name, methods, nMethods);
3173
3174     return 0;
3175 }
3176
3177
3178 /* UnregisterNatives ***********************************************************
3179
3180    Unregisters native methods of a class. The class goes back to the
3181    state before it was linked or registered with its native method
3182    functions.
3183
3184    This function should not be used in normal native code. Instead, it
3185    provides special programs a way to reload and relink native
3186    libraries.
3187
3188 *******************************************************************************/
3189
3190 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3191 {
3192         STATISTICS(jniinvokation());
3193
3194         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3195
3196     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3197
3198     return 0;
3199 }
3200
3201
3202 /* Monitor Operations *********************************************************/
3203
3204 /* MonitorEnter ****************************************************************
3205
3206    Enters the monitor associated with the underlying Java object
3207    referred to by obj.
3208
3209 *******************************************************************************/
3210
3211 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3212 {
3213         STATISTICS(jniinvokation());
3214
3215         if (obj == NULL) {
3216                 exceptions_throw_nullpointerexception();
3217                 return JNI_ERR;
3218         }
3219
3220         LOCK_MONITOR_ENTER(obj);
3221
3222         return JNI_OK;
3223 }
3224
3225
3226 /* MonitorExit *****************************************************************
3227
3228    The current thread must be the owner of the monitor associated with
3229    the underlying Java object referred to by obj. The thread
3230    decrements the counter indicating the number of times it has
3231    entered this monitor. If the value of the counter becomes zero, the
3232    current thread releases the monitor.
3233
3234 *******************************************************************************/
3235
3236 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3237 {
3238         STATISTICS(jniinvokation());
3239
3240         if (obj == NULL) {
3241                 exceptions_throw_nullpointerexception();
3242                 return JNI_ERR;
3243         }
3244
3245         LOCK_MONITOR_EXIT(obj);
3246
3247         return JNI_OK;
3248 }
3249
3250
3251 /* JavaVM Interface ***********************************************************/
3252
3253 /* GetJavaVM *******************************************************************
3254
3255    Returns the Java VM interface (used in the Invocation API)
3256    associated with the current thread. The result is placed at the
3257    location pointed to by the second argument, vm.
3258
3259 *******************************************************************************/
3260
3261 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3262 {
3263         STATISTICS(jniinvokation());
3264
3265     *vm = (JavaVM *) _Jv_jvm;
3266
3267         return 0;
3268 }
3269
3270
3271 /* GetStringRegion *************************************************************
3272
3273    Copies len number of Unicode characters beginning at offset start
3274    to the given buffer buf.
3275
3276    Throws StringIndexOutOfBoundsException on index overflow.
3277
3278 *******************************************************************************/
3279
3280 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3281                                                          jchar *buf)
3282 {
3283         java_lang_String        *s;
3284         java_handle_chararray_t *ca;
3285
3286         STATISTICS(jniinvokation());
3287
3288         s  = (java_lang_String *) str;
3289         LLNI_field_get_ref(s, value, ca);
3290
3291         if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3292                 (start + len > LLNI_field_direct(s, count))) {
3293                 exceptions_throw_stringindexoutofboundsexception();
3294                 return;
3295         }
3296
3297         MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3298 }
3299
3300
3301 /* GetStringUTFRegion **********************************************************
3302
3303     Translates len number of Unicode characters beginning at offset
3304     start into UTF-8 format and place the result in the given buffer
3305     buf.
3306
3307     Throws StringIndexOutOfBoundsException on index overflow. 
3308
3309 *******************************************************************************/
3310
3311 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3312                                                                 jsize len, char *buf)
3313 {
3314         java_lang_String        *s;
3315         java_handle_chararray_t *ca;
3316         s4                       i;
3317         int32_t                  count;
3318         int32_t                  offset;
3319
3320         TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3321
3322         s  = (java_lang_String *) str;
3323         LLNI_field_get_ref(s, value, ca);
3324         LLNI_field_get_val(s, count, count);
3325         LLNI_field_get_val(s, offset, offset);
3326
3327         if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3328                 exceptions_throw_stringindexoutofboundsexception();
3329                 return;
3330         }
3331
3332         for (i = 0; i < len; i++)
3333                 buf[i] = LLNI_array_direct(ca, offset + start + i);
3334
3335         buf[i] = '\0';
3336 }
3337
3338
3339 /* GetPrimitiveArrayCritical ***************************************************
3340
3341    Obtain a direct pointer to array elements.
3342
3343 *******************************************************************************/
3344
3345 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3346                                                                                 jboolean *isCopy)
3347 {
3348         java_handle_bytearray_t *ba;
3349         jbyte                   *bp;
3350
3351         ba = (java_handle_bytearray_t *) array;
3352
3353         /* do the same as Kaffe does */
3354
3355         bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3356
3357         return (void *) bp;
3358 }
3359
3360
3361 /* ReleasePrimitiveArrayCritical ***********************************************
3362
3363    No specific documentation.
3364
3365 *******************************************************************************/
3366
3367 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3368                                                                                    void *carray, jint mode)
3369 {
3370         STATISTICS(jniinvokation());
3371
3372         /* do the same as Kaffe does */
3373
3374         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3375                                                                          mode);
3376 }
3377
3378
3379 /* GetStringCritical ***********************************************************
3380
3381    The semantics of these two functions are similar to the existing
3382    Get/ReleaseStringChars functions.
3383
3384 *******************************************************************************/
3385
3386 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3387                                                                            jboolean *isCopy)
3388 {
3389         STATISTICS(jniinvokation());
3390
3391         return _Jv_JNI_GetStringChars(env, string, isCopy);
3392 }
3393
3394
3395 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3396                                                                    const jchar *cstring)
3397 {
3398         STATISTICS(jniinvokation());
3399
3400         _Jv_JNI_ReleaseStringChars(env, string, cstring);
3401 }
3402
3403
3404 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3405 {
3406         STATISTICS(jniinvokation());
3407
3408         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3409
3410         return obj;
3411 }
3412
3413
3414 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3415 {
3416         STATISTICS(jniinvokation());
3417
3418         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3419 }
3420
3421
3422 /* NewGlobalRef ****************************************************************
3423
3424    Creates a new global reference to the object referred to by the obj
3425    argument.
3426
3427 *******************************************************************************/
3428     
3429 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3430 {
3431         hashtable_global_ref_entry *gre;
3432         u4   key;                           /* hashkey                            */
3433         u4   slot;                          /* slot in hashtable                  */
3434         java_handle_t *o;
3435
3436         STATISTICS(jniinvokation());
3437
3438         o = (java_handle_t *) obj;
3439
3440         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3441
3442         LLNI_CRITICAL_START;
3443
3444         /* normally addresses are aligned to 4, 8 or 16 bytes */
3445
3446 #if defined(ENABLE_GC_CACAO)
3447         key  = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3448 #else
3449         key  = ((u4) (ptrint) o) >> 4;             /* align to 16-byte boundaries */
3450 #endif
3451         slot = key & (hashtable_global_ref->size - 1);
3452         gre  = hashtable_global_ref->ptr[slot];
3453         
3454         /* search external hash chain for the entry */
3455
3456         while (gre) {
3457                 if (gre->o == LLNI_DIRECT(o)) {
3458                         /* global object found, increment the reference */
3459
3460                         gre->refs++;
3461
3462                         break;
3463                 }
3464
3465                 gre = gre->hashlink;                /* next element in external chain */
3466         }
3467
3468         /* global ref not found, create a new one */
3469
3470         if (gre == NULL) {
3471                 gre = NEW(hashtable_global_ref_entry);
3472
3473 #if defined(ENABLE_GC_CACAO)
3474                 /* register global ref with the GC */
3475
3476                 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3477 #endif
3478
3479                 gre->o    = LLNI_DIRECT(o);
3480                 gre->refs = 1;
3481
3482                 /* insert entry into hashtable */
3483
3484                 gre->hashlink = hashtable_global_ref->ptr[slot];
3485
3486                 hashtable_global_ref->ptr[slot] = gre;
3487
3488                 /* update number of hashtable-entries */
3489
3490                 hashtable_global_ref->entries++;
3491         }
3492
3493         LLNI_CRITICAL_END;
3494
3495         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3496
3497 #if defined(ENABLE_HANDLES)
3498         return gre;
3499 #else
3500         return obj;
3501 #endif
3502 }
3503
3504
3505 /* DeleteGlobalRef *************************************************************
3506
3507    Deletes the global reference pointed to by globalRef.
3508
3509 *******************************************************************************/
3510
3511 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3512 {
3513         hashtable_global_ref_entry *gre;
3514         hashtable_global_ref_entry *prevgre;
3515         u4   key;                           /* hashkey                            */
3516         u4   slot;                          /* slot in hashtable                  */
3517         java_handle_t              *o;
3518
3519         STATISTICS(jniinvokation());
3520
3521         o = (java_handle_t *) globalRef;
3522
3523         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3524
3525         LLNI_CRITICAL_START;
3526
3527         /* normally addresses are aligned to 4, 8 or 16 bytes */
3528
3529 #if defined(ENABLE_GC_CACAO)
3530         key  = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3531 #else
3532         key  = ((u4) (ptrint) o) >> 4;             /* align to 16-byte boundaries */
3533 #endif
3534         slot = key & (hashtable_global_ref->size - 1);
3535         gre  = hashtable_global_ref->ptr[slot];
3536
3537         /* initialize prevgre */
3538
3539         prevgre = NULL;
3540
3541         /* search external hash chain for the entry */
3542
3543         while (gre) {
3544                 if (gre->o == LLNI_DIRECT(o)) {
3545                         /* global object found, decrement the reference count */
3546
3547                         gre->refs--;
3548
3549                         /* if reference count is 0, remove the entry */
3550
3551                         if (gre->refs == 0) {
3552                                 /* special handling if it's the first in the chain */
3553
3554                                 if (prevgre == NULL)
3555                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
3556                                 else
3557                                         prevgre->hashlink = gre->hashlink;
3558
3559 #if defined(ENABLE_GC_CACAO)
3560                                 /* unregister global ref with the GC */
3561
3562                                 gc_reference_unregister(&(gre->o));
3563 #endif
3564
3565                                 FREE(gre, hashtable_global_ref_entry);
3566                         }
3567
3568                         LLNI_CRITICAL_END;
3569
3570                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3571
3572                         return;
3573                 }
3574
3575                 prevgre = gre;                    /* save current pointer for removal */
3576                 gre     = gre->hashlink;            /* next element in external chain */
3577         }
3578
3579         log_println("JNI-DeleteGlobalRef: global reference not found");
3580
3581         LLNI_CRITICAL_END;
3582
3583         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3584 }
3585
3586
3587 /* ExceptionCheck **************************************************************
3588
3589    Returns JNI_TRUE when there is a pending exception; otherwise,
3590    returns JNI_FALSE.
3591
3592 *******************************************************************************/
3593
3594 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3595 {
3596         java_handle_t *o;
3597
3598         STATISTICS(jniinvokation());
3599
3600         o = exceptions_get_exception();
3601
3602         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3603 }
3604
3605
3606 /* New JNI 1.4 functions ******************************************************/
3607
3608 /* NewDirectByteBuffer *********************************************************
3609
3610    Allocates and returns a direct java.nio.ByteBuffer referring to the
3611    block of memory starting at the memory address address and
3612    extending capacity bytes.
3613
3614 *******************************************************************************/
3615
3616 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3617 {
3618 #if defined(ENABLE_JAVASE)
3619 # if defined(WITH_CLASSPATH_GNU)
3620         java_handle_t           *nbuf;
3621
3622 # if SIZEOF_VOID_P == 8
3623         gnu_classpath_Pointer64 *paddress;
3624 # else
3625         gnu_classpath_Pointer32 *paddress;
3626 # endif
3627
3628         TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3629
3630         /* alocate a gnu.classpath.Pointer{32,64} object */
3631
3632 # if SIZEOF_VOID_P == 8
3633         if (!(paddress = (gnu_classpath_Pointer64 *)
3634                   builtin_new(class_gnu_classpath_Pointer64)))
3635 # else
3636         if (!(paddress = (gnu_classpath_Pointer32 *)
3637                   builtin_new(class_gnu_classpath_Pointer32)))
3638 # endif
3639                 return NULL;
3640
3641         /* fill gnu.classpath.Pointer{32,64} with address */
3642
3643         LLNI_field_set_val(paddress, data, (ptrint) address);
3644
3645         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3646
3647         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3648                                                          (jmethodID) dbbirw_init, NULL, paddress,
3649                                                          (jint) capacity, (jint) capacity, (jint) 0);
3650
3651         /* add local reference and return the value */
3652
3653         return _Jv_JNI_NewLocalRef(env, nbuf);
3654
3655 # elif defined(WITH_CLASSPATH_SUN)
3656
3657         jobject o;
3658         int64_t addr;
3659         int32_t cap;
3660
3661         TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3662
3663         /* Be paranoid about address sign-extension. */
3664
3665         addr = (int64_t) ((uintptr_t) address);
3666         cap  = (int32_t) capacity;
3667
3668         o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3669                                                   (jmethodID) dbb_init, addr, cap);
3670
3671         /* Add local reference and return the value. */
3672
3673         return _Jv_JNI_NewLocalRef(env, o);
3674
3675 # else
3676 #  error unknown classpath configuration
3677 # endif
3678
3679 #else
3680         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3681
3682         /* keep compiler happy */
3683
3684         return NULL;
3685 #endif
3686 }
3687
3688
3689 /* GetDirectBufferAddress ******************************************************
3690
3691    Fetches and returns the starting address of the memory region
3692    referenced by the given direct java.nio.Buffer.
3693
3694 *******************************************************************************/
3695
3696 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3697 {
3698 #if defined(ENABLE_JAVASE)
3699 # if defined(WITH_CLASSPATH_GNU)
3700
3701         java_nio_DirectByteBufferImpl *nbuf;
3702 #  if SIZEOF_VOID_P == 8
3703         gnu_classpath_Pointer64       *paddress;
3704 #  else
3705         gnu_classpath_Pointer32       *paddress;
3706 #  endif
3707         void                          *address;
3708
3709         TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3710
3711         if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3712                 return NULL;
3713
3714         nbuf = (java_nio_DirectByteBufferImpl *) buf;
3715
3716 #  if SIZEOF_VOID_P == 8
3717         LLNI_field_get_ref(nbuf, address, paddress);
3718         /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3719 #  else
3720         LLNI_field_get_ref(nbuf, address, paddress); 
3721         /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3722 #  endif
3723
3724         if (paddress == NULL)
3725                 return NULL;
3726
3727         LLNI_field_get_val(paddress, data, address);
3728         /* this was the cast to avaoid warning: (void *) paddress->data */
3729
3730         return address;
3731
3732 # elif defined(WITH_CLASSPATH_SUN)
3733
3734         java_nio_Buffer *o;
3735         int64_t          address;
3736         void            *p;
3737
3738         TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3739
3740         if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3741                 return NULL;
3742
3743         o = (java_nio_Buffer *) buf;
3744
3745         LLNI_field_get_val(o, address, address);
3746
3747         p = (void *) (intptr_t) address;
3748
3749         return p;
3750
3751 # else
3752 #  error unknown classpath configuration
3753 # endif
3754
3755 #else
3756
3757         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3758
3759         /* keep compiler happy */
3760
3761         return NULL;
3762
3763 #endif
3764 }
3765
3766
3767 /* GetDirectBufferCapacity *****************************************************
3768
3769    Fetches and returns the capacity in bytes of the memory region
3770    referenced by the given direct java.nio.Buffer.
3771
3772 *******************************************************************************/
3773
3774 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3775 {
3776 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3777         java_handle_t   *o;
3778         java_nio_Buffer *nbuf;
3779         jlong            capacity;
3780
3781         STATISTICS(jniinvokation());
3782
3783         o = (java_handle_t *) buf;
3784
3785         if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3786                 return -1;
3787
3788         nbuf = (java_nio_Buffer *) o;
3789
3790         LLNI_field_get_val(nbuf, cap, capacity);
3791
3792         return capacity;
3793 #else
3794         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3795
3796         /* keep compiler happy */
3797
3798         return 0;
3799 #endif
3800 }
3801
3802
3803 /* GetObjectRefType ************************************************************
3804
3805    Returns the type of the object referred to by the obj argument. The
3806    argument obj can either be a local, global or weak global
3807    reference.
3808
3809 *******************************************************************************/
3810
3811 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3812 {
3813         log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3814
3815         return -1;
3816 }
3817
3818
3819 /* DestroyJavaVM ***************************************************************
3820
3821    Unloads a Java VM and reclaims its resources. Only the main thread
3822    can unload the VM. The system waits until the main thread is only
3823    remaining user thread before it destroys the VM.
3824
3825 *******************************************************************************/
3826
3827 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3828 {
3829         int32_t status;
3830
3831         TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3832
3833     status = vm_destroy(vm);
3834
3835         return status;
3836 }
3837
3838
3839 /* AttachCurrentThread *********************************************************
3840
3841    Attaches the current thread to a Java VM. Returns a JNI interface
3842    pointer in the JNIEnv argument.
3843
3844    Trying to attach a thread that is already attached is a no-op.
3845
3846    A native thread cannot be attached simultaneously to two Java VMs.
3847
3848    When a thread is attached to the VM, the context class loader is
3849    the bootstrap loader.
3850
3851 *******************************************************************************/
3852
3853 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3854 {
3855         JavaVMAttachArgs *vm_aargs;
3856
3857 #if defined(ENABLE_THREADS)
3858         if (threads_get_current_threadobject() == NULL) {
3859                 vm_aargs = (JavaVMAttachArgs *) thr_args;
3860
3861                 if (vm_aargs != NULL) {
3862                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
3863                                 (vm_aargs->version != JNI_VERSION_1_4))
3864                                 return JNI_EVERSION;
3865                 }
3866
3867                 if (!threads_attach_current_thread(vm_aargs, false))
3868                         return JNI_ERR;
3869
3870                 if (!localref_table_init())
3871                         return JNI_ERR;
3872         }
3873 #endif
3874
3875         *p_env = _Jv_env;
3876
3877         return JNI_OK;
3878 }
3879
3880
3881 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3882 {
3883         STATISTICS(jniinvokation());
3884
3885         return jni_attach_current_thread(p_env, thr_args, false);
3886 }
3887
3888
3889 /* DetachCurrentThread *********************************************************
3890
3891    Detaches the current thread from a Java VM. All Java monitors held
3892    by this thread are released. All Java threads waiting for this
3893    thread to die are notified.
3894
3895    In JDK 1.1, the main thread cannot be detached from the VM. It must
3896    call DestroyJavaVM to unload the entire VM.
3897
3898    In the JDK, the main thread can be detached from the VM.
3899
3900    The main thread, which is the thread that created the Java VM,
3901    cannot be detached from the VM. Instead, the main thread must call
3902    JNI_DestroyJavaVM() to unload the entire VM.
3903
3904 *******************************************************************************/
3905
3906 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3907 {
3908 #if defined(ENABLE_THREADS)
3909         threadobject *thread;
3910
3911         STATISTICS(jniinvokation());
3912
3913         thread = threads_get_current_threadobject();
3914
3915         if (thread == NULL)
3916                 return JNI_ERR;
3917
3918         if (!localref_table_destroy())
3919                 return JNI_ERR;
3920
3921         if (!threads_detach_thread(thread))
3922                 return JNI_ERR;
3923 #endif
3924
3925         return JNI_OK;
3926 }
3927
3928
3929 /* GetEnv **********************************************************************
3930
3931    If the current thread is not attached to the VM, sets *env to NULL,
3932    and returns JNI_EDETACHED. If the specified version is not
3933    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3934    sets *env to the appropriate interface, and returns JNI_OK.
3935
3936 *******************************************************************************/
3937
3938 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3939 {
3940         STATISTICS(jniinvokation());
3941
3942 #if defined(ENABLE_THREADS)
3943         if (threads_get_current_threadobject() == NULL) {
3944                 *env = NULL;
3945
3946                 return JNI_EDETACHED;
3947         }
3948 #endif
3949
3950         /* check the JNI version */
3951
3952         switch (version) {
3953         case JNI_VERSION_1_1:
3954         case JNI_VERSION_1_2:
3955         case JNI_VERSION_1_4:
3956                 *env = _Jv_env;
3957                 return JNI_OK;
3958
3959         default:
3960                 ;
3961         }
3962
3963 #if defined(ENABLE_JVMTI)
3964         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
3965                 == JVMTI_VERSION_INTERFACE_JVMTI) {
3966
3967                 *env = (void *) jvmti_new_environment();
3968
3969                 if (env != NULL)
3970                         return JNI_OK;
3971         }
3972 #endif
3973         
3974         *env = NULL;
3975
3976         return JNI_EVERSION;
3977 }
3978
3979
3980 /* AttachCurrentThreadAsDaemon *************************************************
3981
3982    Same semantics as AttachCurrentThread, but the newly-created
3983    java.lang.Thread instance is a daemon.
3984
3985    If the thread has already been attached via either
3986    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3987    simply sets the value pointed to by penv to the JNIEnv of the
3988    current thread. In this case neither AttachCurrentThread nor this
3989    routine have any effect on the daemon status of the thread.
3990
3991 *******************************************************************************/
3992
3993 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3994 {
3995         STATISTICS(jniinvokation());
3996
3997         return jni_attach_current_thread(penv, args, true);
3998 }
3999
4000
4001 /* JNI invocation table *******************************************************/
4002
4003 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
4004         NULL,
4005         NULL,
4006         NULL,
4007
4008         _Jv_JNI_DestroyJavaVM,
4009         _Jv_JNI_AttachCurrentThread,
4010         _Jv_JNI_DetachCurrentThread,
4011         _Jv_JNI_GetEnv,
4012         _Jv_JNI_AttachCurrentThreadAsDaemon
4013 };
4014
4015
4016 /* JNI function table *********************************************************/
4017
4018 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4019         NULL,
4020         NULL,
4021         NULL,
4022         NULL,    
4023         _Jv_JNI_GetVersion,
4024
4025         _Jv_JNI_DefineClass,
4026         _Jv_JNI_FindClass,
4027         _Jv_JNI_FromReflectedMethod,
4028         _Jv_JNI_FromReflectedField,
4029         _Jv_JNI_ToReflectedMethod,
4030         _Jv_JNI_GetSuperclass,
4031         _Jv_JNI_IsAssignableFrom,
4032         _Jv_JNI_ToReflectedField,
4033
4034         _Jv_JNI_Throw,
4035         _Jv_JNI_ThrowNew,
4036         _Jv_JNI_ExceptionOccurred,
4037         _Jv_JNI_ExceptionDescribe,
4038         _Jv_JNI_ExceptionClear,
4039         _Jv_JNI_FatalError,
4040         _Jv_JNI_PushLocalFrame,
4041         _Jv_JNI_PopLocalFrame,
4042
4043         _Jv_JNI_NewGlobalRef,
4044         _Jv_JNI_DeleteGlobalRef,
4045         _Jv_JNI_DeleteLocalRef,
4046         _Jv_JNI_IsSameObject,
4047         _Jv_JNI_NewLocalRef,
4048         _Jv_JNI_EnsureLocalCapacity,
4049
4050         _Jv_JNI_AllocObject,
4051         _Jv_JNI_NewObject,
4052         _Jv_JNI_NewObjectV,
4053         _Jv_JNI_NewObjectA,
4054
4055         _Jv_JNI_GetObjectClass,
4056         _Jv_JNI_IsInstanceOf,
4057
4058         _Jv_JNI_GetMethodID,
4059
4060         _Jv_JNI_CallObjectMethod,
4061         _Jv_JNI_CallObjectMethodV,
4062         _Jv_JNI_CallObjectMethodA,
4063         _Jv_JNI_CallBooleanMethod,
4064         _Jv_JNI_CallBooleanMethodV,
4065         _Jv_JNI_CallBooleanMethodA,
4066         _Jv_JNI_CallByteMethod,
4067         _Jv_JNI_CallByteMethodV,
4068         _Jv_JNI_CallByteMethodA,
4069         _Jv_JNI_CallCharMethod,
4070         _Jv_JNI_CallCharMethodV,
4071         _Jv_JNI_CallCharMethodA,
4072         _Jv_JNI_CallShortMethod,
4073         _Jv_JNI_CallShortMethodV,
4074         _Jv_JNI_CallShortMethodA,
4075         _Jv_JNI_CallIntMethod,
4076         _Jv_JNI_CallIntMethodV,
4077         _Jv_JNI_CallIntMethodA,
4078         _Jv_JNI_CallLongMethod,
4079         _Jv_JNI_CallLongMethodV,
4080         _Jv_JNI_CallLongMethodA,
4081         _Jv_JNI_CallFloatMethod,
4082         _Jv_JNI_CallFloatMethodV,
4083         _Jv_JNI_CallFloatMethodA,
4084         _Jv_JNI_CallDoubleMethod,
4085         _Jv_JNI_CallDoubleMethodV,
4086         _Jv_JNI_CallDoubleMethodA,
4087         _Jv_JNI_CallVoidMethod,
4088         _Jv_JNI_CallVoidMethodV,
4089         _Jv_JNI_CallVoidMethodA,
4090
4091         _Jv_JNI_CallNonvirtualObjectMethod,
4092         _Jv_JNI_CallNonvirtualObjectMethodV,
4093         _Jv_JNI_CallNonvirtualObjectMethodA,
4094         _Jv_JNI_CallNonvirtualBooleanMethod,
4095         _Jv_JNI_CallNonvirtualBooleanMethodV,
4096         _Jv_JNI_CallNonvirtualBooleanMethodA,
4097         _Jv_JNI_CallNonvirtualByteMethod,
4098         _Jv_JNI_CallNonvirtualByteMethodV,
4099         _Jv_JNI_CallNonvirtualByteMethodA,
4100         _Jv_JNI_CallNonvirtualCharMethod,
4101         _Jv_JNI_CallNonvirtualCharMethodV,
4102         _Jv_JNI_CallNonvirtualCharMethodA,
4103         _Jv_JNI_CallNonvirtualShortMethod,
4104         _Jv_JNI_CallNonvirtualShortMethodV,
4105         _Jv_JNI_CallNonvirtualShortMethodA,
4106         _Jv_JNI_CallNonvirtualIntMethod,
4107         _Jv_JNI_CallNonvirtualIntMethodV,
4108         _Jv_JNI_CallNonvirtualIntMethodA,
4109         _Jv_JNI_CallNonvirtualLongMethod,
4110         _Jv_JNI_CallNonvirtualLongMethodV,
4111         _Jv_JNI_CallNonvirtualLongMethodA,
4112         _Jv_JNI_CallNonvirtualFloatMethod,
4113         _Jv_JNI_CallNonvirtualFloatMethodV,
4114         _Jv_JNI_CallNonvirtualFloatMethodA,
4115         _Jv_JNI_CallNonvirtualDoubleMethod,
4116         _Jv_JNI_CallNonvirtualDoubleMethodV,
4117         _Jv_JNI_CallNonvirtualDoubleMethodA,
4118         _Jv_JNI_CallNonvirtualVoidMethod,
4119         _Jv_JNI_CallNonvirtualVoidMethodV,
4120         _Jv_JNI_CallNonvirtualVoidMethodA,
4121
4122         _Jv_JNI_GetFieldID,
4123
4124         _Jv_JNI_GetObjectField,
4125         _Jv_JNI_GetBooleanField,
4126         _Jv_JNI_GetByteField,
4127         _Jv_JNI_GetCharField,
4128         _Jv_JNI_GetShortField,
4129         _Jv_JNI_GetIntField,
4130         _Jv_JNI_GetLongField,
4131         _Jv_JNI_GetFloatField,
4132         _Jv_JNI_GetDoubleField,
4133         _Jv_JNI_SetObjectField,
4134         _Jv_JNI_SetBooleanField,
4135         _Jv_JNI_SetByteField,
4136         _Jv_JNI_SetCharField,
4137         _Jv_JNI_SetShortField,
4138         _Jv_JNI_SetIntField,
4139         _Jv_JNI_SetLongField,
4140         _Jv_JNI_SetFloatField,
4141         _Jv_JNI_SetDoubleField,
4142
4143         _Jv_JNI_GetStaticMethodID,
4144
4145         _Jv_JNI_CallStaticObjectMethod,
4146         _Jv_JNI_CallStaticObjectMethodV,
4147         _Jv_JNI_CallStaticObjectMethodA,
4148         _Jv_JNI_CallStaticBooleanMethod,
4149         _Jv_JNI_CallStaticBooleanMethodV,
4150         _Jv_JNI_CallStaticBooleanMethodA,
4151         _Jv_JNI_CallStaticByteMethod,
4152         _Jv_JNI_CallStaticByteMethodV,
4153         _Jv_JNI_CallStaticByteMethodA,
4154         _Jv_JNI_CallStaticCharMethod,
4155         _Jv_JNI_CallStaticCharMethodV,
4156         _Jv_JNI_CallStaticCharMethodA,
4157         _Jv_JNI_CallStaticShortMethod,
4158         _Jv_JNI_CallStaticShortMethodV,
4159         _Jv_JNI_CallStaticShortMethodA,
4160         _Jv_JNI_CallStaticIntMethod,
4161         _Jv_JNI_CallStaticIntMethodV,
4162         _Jv_JNI_CallStaticIntMethodA,
4163         _Jv_JNI_CallStaticLongMethod,
4164         _Jv_JNI_CallStaticLongMethodV,
4165         _Jv_JNI_CallStaticLongMethodA,
4166         _Jv_JNI_CallStaticFloatMethod,
4167         _Jv_JNI_CallStaticFloatMethodV,
4168         _Jv_JNI_CallStaticFloatMethodA,
4169         _Jv_JNI_CallStaticDoubleMethod,
4170         _Jv_JNI_CallStaticDoubleMethodV,
4171         _Jv_JNI_CallStaticDoubleMethodA,
4172         _Jv_JNI_CallStaticVoidMethod,
4173         _Jv_JNI_CallStaticVoidMethodV,
4174         _Jv_JNI_CallStaticVoidMethodA,
4175
4176         _Jv_JNI_GetStaticFieldID,
4177
4178         _Jv_JNI_GetStaticObjectField,
4179         _Jv_JNI_GetStaticBooleanField,
4180         _Jv_JNI_GetStaticByteField,
4181         _Jv_JNI_GetStaticCharField,
4182         _Jv_JNI_GetStaticShortField,
4183         _Jv_JNI_GetStaticIntField,
4184         _Jv_JNI_GetStaticLongField,
4185         _Jv_JNI_GetStaticFloatField,
4186         _Jv_JNI_GetStaticDoubleField,
4187         _Jv_JNI_SetStaticObjectField,
4188         _Jv_JNI_SetStaticBooleanField,
4189         _Jv_JNI_SetStaticByteField,
4190         _Jv_JNI_SetStaticCharField,
4191         _Jv_JNI_SetStaticShortField,
4192         _Jv_JNI_SetStaticIntField,
4193         _Jv_JNI_SetStaticLongField,
4194         _Jv_JNI_SetStaticFloatField,
4195         _Jv_JNI_SetStaticDoubleField,
4196
4197         _Jv_JNI_NewString,
4198         _Jv_JNI_GetStringLength,
4199         _Jv_JNI_GetStringChars,
4200         _Jv_JNI_ReleaseStringChars,
4201
4202         _Jv_JNI_NewStringUTF,
4203         _Jv_JNI_GetStringUTFLength,
4204         _Jv_JNI_GetStringUTFChars,
4205         _Jv_JNI_ReleaseStringUTFChars,
4206
4207         _Jv_JNI_GetArrayLength,
4208
4209         _Jv_JNI_NewObjectArray,
4210         _Jv_JNI_GetObjectArrayElement,
4211         _Jv_JNI_SetObjectArrayElement,
4212
4213         _Jv_JNI_NewBooleanArray,
4214         _Jv_JNI_NewByteArray,
4215         _Jv_JNI_NewCharArray,
4216         _Jv_JNI_NewShortArray,
4217         _Jv_JNI_NewIntArray,
4218         _Jv_JNI_NewLongArray,
4219         _Jv_JNI_NewFloatArray,
4220         _Jv_JNI_NewDoubleArray,
4221
4222         _Jv_JNI_GetBooleanArrayElements,
4223         _Jv_JNI_GetByteArrayElements,
4224         _Jv_JNI_GetCharArrayElements,
4225         _Jv_JNI_GetShortArrayElements,
4226         _Jv_JNI_GetIntArrayElements,
4227         _Jv_JNI_GetLongArrayElements,
4228         _Jv_JNI_GetFloatArrayElements,
4229         _Jv_JNI_GetDoubleArrayElements,
4230
4231         _Jv_JNI_ReleaseBooleanArrayElements,
4232         _Jv_JNI_ReleaseByteArrayElements,
4233         _Jv_JNI_ReleaseCharArrayElements,
4234         _Jv_JNI_ReleaseShortArrayElements,
4235         _Jv_JNI_ReleaseIntArrayElements,
4236         _Jv_JNI_ReleaseLongArrayElements,
4237         _Jv_JNI_ReleaseFloatArrayElements,
4238         _Jv_JNI_ReleaseDoubleArrayElements,
4239
4240         _Jv_JNI_GetBooleanArrayRegion,
4241         _Jv_JNI_GetByteArrayRegion,
4242         _Jv_JNI_GetCharArrayRegion,
4243         _Jv_JNI_GetShortArrayRegion,
4244         _Jv_JNI_GetIntArrayRegion,
4245         _Jv_JNI_GetLongArrayRegion,
4246         _Jv_JNI_GetFloatArrayRegion,
4247         _Jv_JNI_GetDoubleArrayRegion,
4248         _Jv_JNI_SetBooleanArrayRegion,
4249         _Jv_JNI_SetByteArrayRegion,
4250         _Jv_JNI_SetCharArrayRegion,
4251         _Jv_JNI_SetShortArrayRegion,
4252         _Jv_JNI_SetIntArrayRegion,
4253         _Jv_JNI_SetLongArrayRegion,
4254         _Jv_JNI_SetFloatArrayRegion,
4255         _Jv_JNI_SetDoubleArrayRegion,
4256
4257         _Jv_JNI_RegisterNatives,
4258         _Jv_JNI_UnregisterNatives,
4259
4260         _Jv_JNI_MonitorEnter,
4261         _Jv_JNI_MonitorExit,
4262
4263         _Jv_JNI_GetJavaVM,
4264
4265         /* New JNI 1.2 functions. */
4266
4267         _Jv_JNI_GetStringRegion,
4268         _Jv_JNI_GetStringUTFRegion,
4269
4270         _Jv_JNI_GetPrimitiveArrayCritical,
4271         _Jv_JNI_ReleasePrimitiveArrayCritical,
4272
4273         _Jv_JNI_GetStringCritical,
4274         _Jv_JNI_ReleaseStringCritical,
4275
4276         _Jv_JNI_NewWeakGlobalRef,
4277         _Jv_JNI_DeleteWeakGlobalRef,
4278
4279         _Jv_JNI_ExceptionCheck,
4280
4281         /* New JNI 1.4 functions. */
4282
4283         _Jv_JNI_NewDirectByteBuffer,
4284         _Jv_JNI_GetDirectBufferAddress,
4285         _Jv_JNI_GetDirectBufferCapacity,
4286
4287         /* New JNI 1.6 functions. */
4288
4289         jni_GetObjectRefType
4290 };
4291
4292
4293 /* Invocation API Functions ***************************************************/
4294
4295 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4296
4297    Returns a default configuration for the Java VM.
4298
4299 *******************************************************************************/
4300
4301 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4302 {
4303         JavaVMInitArgs *_vm_args;
4304
4305         _vm_args = (JavaVMInitArgs *) vm_args;
4306
4307         /* GNU classpath currently supports JNI 1.2 */
4308
4309         switch (_vm_args->version) {
4310     case JNI_VERSION_1_1:
4311                 _vm_args->version = JNI_VERSION_1_1;
4312                 break;
4313
4314     case JNI_VERSION_1_2:
4315     case JNI_VERSION_1_4:
4316                 _vm_args->ignoreUnrecognized = JNI_FALSE;
4317                 _vm_args->options = NULL;
4318                 _vm_args->nOptions = 0;
4319                 break;
4320
4321     default:
4322                 return -1;
4323         }
4324   
4325         return 0;
4326 }
4327
4328
4329 /* JNI_GetCreatedJavaVMs *******************************************************
4330
4331    Returns all Java VMs that have been created. Pointers to VMs are written in
4332    the buffer vmBuf in the order they are created. At most bufLen number of
4333    entries will be written. The total number of created VMs is returned in
4334    *nVMs.
4335
4336 *******************************************************************************/
4337
4338 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4339 {
4340         TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4341
4342         if (bufLen <= 0)
4343                 return JNI_ERR;
4344
4345         /* We currently only support 1 VM running. */
4346
4347         vmBuf[0] = (JavaVM *) _Jv_jvm;
4348         *nVMs    = 1;
4349
4350     return JNI_OK;
4351 }
4352
4353
4354 /* JNI_CreateJavaVM ************************************************************
4355
4356    Loads and initializes a Java VM. The current thread becomes the main thread.
4357    Sets the env argument to the JNI interface pointer of the main thread.
4358
4359 *******************************************************************************/
4360
4361 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4362 {
4363         TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4364
4365         /* actually create the JVM */
4366
4367         if (!vm_createjvm(p_vm, p_env, vm_args))
4368                 return JNI_ERR;
4369
4370         return JNI_OK;
4371 }
4372
4373
4374 /*
4375  * These are local overrides for various environment variables in Emacs.
4376  * Please do not remove this and leave it at the end of the file, where
4377  * Emacs will automagically detect them.
4378  * ---------------------------------------------------------------------
4379  * Local variables:
4380  * mode: c
4381  * indent-tabs-mode: t
4382  * c-basic-offset: 4
4383  * tab-width: 4
4384  * End:
4385  * vim:noexpandtab:sw=4:ts=4:
4386  */