* configure.ac: Added missing newline.
[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         utf             *u;
998         classinfo       *cc;
999         classinfo       *c;
1000         java_lang_Class *co;
1001
1002         STATISTICS(jniinvokation());
1003
1004         u = utf_new_char_classname((char *) name);
1005
1006         /* Check stacktrace for classloader, if one found use it,
1007            otherwise use the system classloader. */
1008
1009         /* Quote from the JNI documentation:
1010          
1011            In the Java 2 Platform, FindClass locates the class loader
1012            associated with the current native method.  If the native code
1013            belongs to a system class, no class loader will be
1014            involved. Otherwise, the proper class loader will be invoked to
1015            load and link the named class. When FindClass is called through
1016            the Invocation Interface, there is no current native method or
1017            its associated class loader. In that case, the result of
1018            ClassLoader.getBaseClassLoader is used." */
1019
1020         cc = stacktrace_getCurrentClass();
1021
1022         if (cc == NULL)
1023                 c = load_class_from_sysloader(u);
1024         else
1025                 c = load_class_from_classloader(u, cc->classloader);
1026
1027         if (c == NULL)
1028                 return NULL;
1029
1030         if (!link_class(c))
1031                 return NULL;
1032
1033         co = LLNI_classinfo_wrap(c);
1034
1035         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1036 #else
1037         vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
1038
1039         /* keep compiler happy */
1040
1041         return NULL;
1042 #endif
1043 }
1044   
1045
1046 /* GetSuperclass ***************************************************************
1047
1048    If clazz represents any class other than the class Object, then
1049    this function returns the object that represents the superclass of
1050    the class specified by clazz.
1051
1052 *******************************************************************************/
1053  
1054 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
1055 {
1056         classinfo       *c;
1057         classinfo       *super;
1058         java_lang_Class *co;
1059
1060         TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
1061
1062         c = LLNI_classinfo_unwrap(sub);
1063
1064         if (c == NULL)
1065                 return NULL;
1066
1067         super = class_get_superclass(c);
1068
1069         co = LLNI_classinfo_wrap(super);
1070
1071         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1072 }
1073   
1074  
1075 /* IsAssignableFrom ************************************************************
1076
1077    Determines whether an object of sub can be safely cast to sup.
1078
1079 *******************************************************************************/
1080
1081 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1082 {
1083         java_lang_Class *csup;
1084         java_lang_Class *csub;
1085
1086         csup = (java_lang_Class *) sup;
1087         csub = (java_lang_Class *) sub;
1088
1089         STATISTICS(jniinvokation());
1090
1091         return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1092 }
1093
1094
1095 /* Throw ***********************************************************************
1096
1097    Causes a java.lang.Throwable object to be thrown.
1098
1099 *******************************************************************************/
1100
1101 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1102 {
1103         java_handle_t *o;
1104
1105         STATISTICS(jniinvokation());
1106
1107         o = (java_handle_t *) obj;
1108
1109         exceptions_set_exception(o);
1110
1111         return JNI_OK;
1112 }
1113
1114
1115 /* ThrowNew ********************************************************************
1116
1117    Constructs an exception object from the specified class with the
1118    message specified by message and causes that exception to be
1119    thrown.
1120
1121 *******************************************************************************/
1122
1123 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1124 {
1125         classinfo     *c;
1126         java_handle_t *o;
1127         java_handle_t *s;
1128
1129         STATISTICS(jniinvokation());
1130
1131         c = LLNI_classinfo_unwrap(clazz);
1132         if (msg == NULL)
1133                 msg = "";
1134         s = javastring_new_from_utf_string(msg);
1135
1136         /* instantiate exception object */
1137
1138         o = native_new_and_init_string(c, s);
1139
1140         if (o == NULL)
1141                 return -1;
1142
1143         exceptions_set_exception(o);
1144
1145         return 0;
1146 }
1147
1148
1149 /* ExceptionOccurred ***********************************************************
1150
1151    Determines if an exception is being thrown. The exception stays
1152    being thrown until either the native code calls ExceptionClear(),
1153    or the Java code handles the exception.
1154
1155 *******************************************************************************/
1156
1157 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1158 {
1159         java_handle_t *o;
1160
1161         TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
1162
1163         o = exceptions_get_exception();
1164
1165         return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1166 }
1167
1168
1169 /* ExceptionDescribe ***********************************************************
1170
1171    Prints an exception and a backtrace of the stack to a system
1172    error-reporting channel, such as stderr. This is a convenience
1173    routine provided for debugging.
1174
1175 *******************************************************************************/
1176
1177 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
1178 {
1179         java_handle_t *o;
1180         classinfo     *c;
1181         methodinfo    *m;
1182
1183         TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
1184
1185         /* Clear exception, because we are probably calling Java code
1186            again. */
1187
1188         o = exceptions_get_and_clear_exception();
1189
1190         if (o != NULL) {
1191                 /* get printStackTrace method from exception class */
1192
1193                 LLNI_class_get(o, c);
1194
1195                 m = class_resolveclassmethod(c,
1196                                                                          utf_printStackTrace,
1197                                                                          utf_void__void,
1198                                                                          NULL,
1199                                                                          true);
1200
1201                 if (m == NULL)
1202                         vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
1203
1204                 /* Print the stacktrace. */
1205
1206                 (void) vm_call_method(m, o);
1207         }
1208 }
1209
1210
1211 /* ExceptionClear **************************************************************
1212
1213    Clears any exception that is currently being thrown. If no
1214    exception is currently being thrown, this routine has no effect.
1215
1216 *******************************************************************************/
1217
1218 void _Jv_JNI_ExceptionClear(JNIEnv *env)
1219 {
1220         STATISTICS(jniinvokation());
1221
1222         exceptions_clear_exception();
1223 }
1224
1225
1226 /* FatalError ******************************************************************
1227
1228    Raises a fatal error and does not expect the VM to recover. This
1229    function does not return.
1230
1231 *******************************************************************************/
1232
1233 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1234 {
1235         STATISTICS(jniinvokation());
1236
1237         /* this seems to be the best way */
1238
1239         vm_abort("JNI Fatal error: %s", msg);
1240 }
1241
1242
1243 /* PushLocalFrame **************************************************************
1244
1245    Creates a new local reference frame, in which at least a given
1246    number of local references can be created.
1247
1248 *******************************************************************************/
1249
1250 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1251 {
1252         STATISTICS(jniinvokation());
1253
1254         if (capacity <= 0)
1255                 return -1;
1256
1257         /* add new local reference frame to current table */
1258
1259         if (!localref_frame_push(capacity))
1260                 return -1;
1261
1262         return 0;
1263 }
1264
1265
1266 /* PopLocalFrame ***************************************************************
1267
1268    Pops off the current local reference frame, frees all the local
1269    references, and returns a local reference in the previous local
1270    reference frame for the given result object.
1271
1272 *******************************************************************************/
1273
1274 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1275 {
1276         STATISTICS(jniinvokation());
1277
1278         /* release all current local frames */
1279
1280         localref_frame_pop_all();
1281
1282         /* add local reference and return the value */
1283
1284         return _Jv_JNI_NewLocalRef(env, result);
1285 }
1286
1287
1288 /* DeleteLocalRef **************************************************************
1289
1290    Deletes the local reference pointed to by localRef.
1291
1292 *******************************************************************************/
1293
1294 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1295 {
1296         java_handle_t  *o;
1297
1298         STATISTICS(jniinvokation());
1299
1300         o = (java_handle_t *) localRef;
1301
1302         /* delete the reference */
1303
1304         localref_del(o);
1305 }
1306
1307
1308 /* IsSameObject ****************************************************************
1309
1310    Tests whether two references refer to the same Java object.
1311
1312 *******************************************************************************/
1313
1314 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1315 {
1316         java_handle_t *o1;
1317         java_handle_t *o2;
1318         jboolean       result;
1319
1320         STATISTICS(jniinvokation());
1321
1322         o1 = (java_handle_t *) ref1;
1323         o2 = (java_handle_t *) ref2;
1324
1325         LLNI_CRITICAL_START;
1326
1327         if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1328                 result = JNI_TRUE;
1329         else
1330                 result = JNI_FALSE;
1331
1332         LLNI_CRITICAL_END;
1333
1334         return result;
1335 }
1336
1337
1338 /* NewLocalRef *****************************************************************
1339
1340    Creates a new local reference that refers to the same object as ref.
1341
1342 *******************************************************************************/
1343
1344 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1345 {
1346         java_handle_t *o;
1347         java_handle_t *localref;
1348
1349         STATISTICS(jniinvokation());
1350
1351         if (ref == NULL)
1352                 return NULL;
1353
1354         o = (java_handle_t *) ref;
1355
1356         /* insert the reference */
1357
1358         localref = localref_add(LLNI_DIRECT(o));
1359
1360         return localref;
1361 }
1362
1363
1364 /* EnsureLocalCapacity *********************************************************
1365
1366    Ensures that at least a given number of local references can be
1367    created in the current thread
1368
1369 *******************************************************************************/
1370
1371 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1372 {
1373         localref_table *lrt;
1374
1375         STATISTICS(jniinvokation());
1376
1377         /* get local reference table (thread specific) */
1378
1379         lrt = LOCALREFTABLE;
1380
1381         /* check if capacity elements are available in the local references table */
1382
1383         if ((lrt->used + capacity) > lrt->capacity)
1384                 return _Jv_JNI_PushLocalFrame(env, capacity);
1385
1386         return 0;
1387 }
1388
1389
1390 /* AllocObject *****************************************************************
1391
1392    Allocates a new Java object without invoking any of the
1393    constructors for the object. Returns a reference to the object.
1394
1395 *******************************************************************************/
1396
1397 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1398 {
1399         classinfo     *c;
1400         java_handle_t *o;
1401
1402         STATISTICS(jniinvokation());
1403
1404         c = LLNI_classinfo_unwrap(clazz);
1405
1406         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1407                 exceptions_throw_instantiationexception(c);
1408                 return NULL;
1409         }
1410                 
1411         o = builtin_new(c);
1412
1413         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1414 }
1415
1416
1417 /* NewObject *******************************************************************
1418
1419    Programmers place all arguments that are to be passed to the
1420    constructor immediately following the methodID
1421    argument. NewObject() accepts these arguments and passes them to
1422    the Java method that the programmer wishes to invoke.
1423
1424 *******************************************************************************/
1425
1426 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1427 {
1428         java_handle_t *o;
1429         classinfo     *c;
1430         methodinfo    *m;
1431         va_list        ap;
1432
1433         STATISTICS(jniinvokation());
1434
1435         c = LLNI_classinfo_unwrap(clazz);
1436         m = (methodinfo *) methodID;
1437
1438         /* create object */
1439
1440         o = builtin_new(c);
1441         
1442         if (o == NULL)
1443                 return NULL;
1444
1445         /* call constructor */
1446
1447         va_start(ap, methodID);
1448         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1449         va_end(ap);
1450
1451         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1452 }
1453
1454
1455 /* NewObjectV ******************************************************************
1456
1457    Programmers place all arguments that are to be passed to the
1458    constructor in an args argument of type va_list that immediately
1459    follows the methodID argument. NewObjectV() accepts these
1460    arguments, and, in turn, passes them to the Java method that the
1461    programmer wishes to invoke.
1462
1463 *******************************************************************************/
1464
1465 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1466                                                    va_list args)
1467 {
1468         java_handle_t *o;
1469         classinfo     *c;
1470         methodinfo    *m;
1471
1472         STATISTICS(jniinvokation());
1473
1474         c = LLNI_classinfo_unwrap(clazz);
1475         m = (methodinfo *) methodID;
1476
1477         /* create object */
1478
1479         o = builtin_new(c);
1480         
1481         if (o == NULL)
1482                 return NULL;
1483
1484         /* call constructor */
1485
1486         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1487
1488         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1489 }
1490
1491
1492 /* NewObjectA ***************************************************************** 
1493
1494    Programmers place all arguments that are to be passed to the
1495    constructor in an args array of jvalues that immediately follows
1496    the methodID argument. NewObjectA() accepts the arguments in this
1497    array, and, in turn, passes them to the Java method that the
1498    programmer wishes to invoke.
1499
1500 *******************************************************************************/
1501
1502 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1503                                                    const jvalue *args)
1504 {
1505         java_handle_t *o;
1506         classinfo     *c;
1507         methodinfo    *m;
1508
1509         STATISTICS(jniinvokation());
1510
1511         c = LLNI_classinfo_unwrap(clazz);
1512         m = (methodinfo *) methodID;
1513
1514         /* create object */
1515
1516         o = builtin_new(c);
1517         
1518         if (o == NULL)
1519                 return NULL;
1520
1521         /* call constructor */
1522
1523         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1524
1525         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1526 }
1527
1528
1529 /* GetObjectClass **************************************************************
1530
1531  Returns the class of an object.
1532
1533 *******************************************************************************/
1534
1535 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1536 {
1537         java_handle_t   *o;
1538         classinfo       *c;
1539         java_lang_Class *co;
1540
1541         STATISTICS(jniinvokation());
1542
1543         o = (java_handle_t *) obj;
1544
1545         if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1546                 return NULL;
1547
1548         LLNI_class_get(o, c);
1549
1550         co = LLNI_classinfo_wrap(c);
1551
1552         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1553 }
1554
1555
1556 /* IsInstanceOf ****************************************************************
1557
1558    Tests whether an object is an instance of a class.
1559
1560 *******************************************************************************/
1561
1562 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1563 {
1564         java_lang_Class  *c;
1565         java_lang_Object *o;
1566
1567         STATISTICS(jniinvokation());
1568
1569         c = (java_lang_Class *) clazz;
1570         o = (java_lang_Object *) obj;
1571
1572         return _Jv_java_lang_Class_isInstance(c, o);
1573 }
1574
1575
1576 /* Reflection Support *********************************************************/
1577
1578 /* FromReflectedMethod *********************************************************
1579
1580    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1581    object to a method ID.
1582   
1583 *******************************************************************************/
1584   
1585 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1586 {
1587 #if defined(ENABLE_JAVASE)
1588         java_handle_t *o;
1589         classinfo     *c;
1590         methodinfo    *m;
1591         s4             slot;
1592
1593         STATISTICS(jniinvokation());
1594
1595         o = (java_handle_t *) method;
1596
1597         if (o == NULL)
1598                 return NULL;
1599         
1600         if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1601                 java_lang_reflect_Method *rm;
1602
1603                 rm   = (java_lang_reflect_Method *) method;
1604                 LLNI_field_get_cls(rm, clazz, c);
1605                 LLNI_field_get_val(rm, slot , slot);
1606         }
1607         else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1608                 java_lang_reflect_Constructor *rc;
1609
1610                 rc   = (java_lang_reflect_Constructor *) method;
1611                 LLNI_field_get_cls(rc, clazz, c);
1612                 LLNI_field_get_val(rc, slot , slot);
1613         }
1614         else
1615                 return NULL;
1616
1617         m = &(c->methods[slot]);
1618
1619         return (jmethodID) m;
1620 #else
1621         vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1622
1623         /* keep compiler happy */
1624
1625         return NULL;
1626 #endif
1627 }
1628
1629
1630 /* FromReflectedField **********************************************************
1631
1632    Converts a java.lang.reflect.Field to a field ID.
1633
1634 *******************************************************************************/
1635  
1636 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1637 {
1638 #if defined(ENABLE_JAVASE)
1639         java_lang_reflect_Field *rf;
1640         classinfo               *c;
1641         fieldinfo               *f;
1642         int32_t                  slot;
1643
1644         STATISTICS(jniinvokation());
1645
1646         rf = (java_lang_reflect_Field *) field;
1647
1648         if (rf == NULL)
1649                 return NULL;
1650
1651         LLNI_field_get_cls(rf, clazz, c);
1652         LLNI_field_get_val(rf, slot , slot);
1653         f = &(c->fields[slot]);
1654
1655         return (jfieldID) f;
1656 #else
1657         vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1658
1659         /* keep compiler happy */
1660
1661         return NULL;
1662 #endif
1663 }
1664
1665
1666 /* ToReflectedMethod ***********************************************************
1667
1668    Converts a method ID derived from cls to an instance of the
1669    java.lang.reflect.Method class or to an instance of the
1670    java.lang.reflect.Constructor class.
1671
1672 *******************************************************************************/
1673
1674 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1675                                                                   jboolean isStatic)
1676 {
1677 #if defined(ENABLE_JAVASE)
1678         methodinfo                    *m;
1679         java_lang_reflect_Constructor *rc;
1680         java_lang_reflect_Method      *rm;
1681
1682         TRACEJNICALLS("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic);
1683
1684         m = (methodinfo *) methodID;
1685
1686         /* HotSpot does the same assert. */
1687
1688         assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1689
1690         if (m->name == utf_init) {
1691                 rc = reflect_constructor_new(m);
1692
1693                 return (jobject) rc;
1694         }
1695         else {
1696                 rm = reflect_method_new(m);
1697
1698                 return (jobject) rm;
1699         }
1700 #else
1701         vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1702
1703         /* keep compiler happy */
1704
1705         return NULL;
1706 #endif
1707 }
1708
1709
1710 /* ToReflectedField ************************************************************
1711
1712    Converts a field ID derived from cls to an instance of the
1713    java.lang.reflect.Field class.
1714
1715 *******************************************************************************/
1716
1717 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1718                                                                  jboolean isStatic)
1719 {
1720         STATISTICS(jniinvokation());
1721
1722         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1723
1724         return NULL;
1725 }
1726
1727
1728 /* Calling Instance Methods ***************************************************/
1729
1730 /* GetMethodID *****************************************************************
1731
1732    Returns the method ID for an instance (nonstatic) method of a class
1733    or interface. The method may be defined in one of the clazz's
1734    superclasses and inherited by clazz. The method is determined by
1735    its name and signature.
1736
1737    GetMethodID() causes an uninitialized class to be initialized.
1738
1739 *******************************************************************************/
1740
1741 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1742                                                           const char *sig)
1743 {
1744         classinfo  *c;
1745         utf        *uname;
1746         utf        *udesc;
1747         methodinfo *m;
1748
1749         STATISTICS(jniinvokation());
1750
1751         c = LLNI_classinfo_unwrap(clazz);
1752
1753         if (c == NULL)
1754                 return NULL;
1755
1756         if (!(c->state & CLASS_INITIALIZED))
1757                 if (!initialize_class(c))
1758                         return NULL;
1759
1760         /* try to get the method of the class or one of it's superclasses */
1761
1762         uname = utf_new_char((char *) name);
1763         udesc = utf_new_char((char *) sig);
1764
1765         m = class_resolvemethod(c, uname, udesc);
1766
1767         if ((m == NULL) || (m->flags & ACC_STATIC)) {
1768                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1769
1770                 return NULL;
1771         }
1772
1773         return (jmethodID) m;
1774 }
1775
1776
1777 /* JNI-functions for calling instance methods *********************************/
1778
1779 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
1780 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
1781                                                                 jmethodID methodID, ...)    \
1782 {                                                           \
1783         java_handle_t *o;                                       \
1784         methodinfo    *m;                                       \
1785         va_list        ap;                                      \
1786         type           ret;                                     \
1787                                                             \
1788         o = (java_handle_t *) obj;                              \
1789         m = (methodinfo *) methodID;                            \
1790                                                             \
1791         va_start(ap, methodID);                                 \
1792         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1793         va_end(ap);                                             \
1794                                                             \
1795         return ret;                                             \
1796 }
1797
1798 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1799 JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
1800 JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
1801 JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
1802 JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
1803 JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
1804 JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
1805 JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
1806
1807
1808 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
1809 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
1810                                                                  jmethodID methodID, va_list args) \
1811 {                                                                  \
1812         java_handle_t *o;                                              \
1813         methodinfo    *m;                                              \
1814         type           ret;                                            \
1815                                                                    \
1816         o = (java_handle_t *) obj;                                     \
1817         m = (methodinfo *) methodID;                                   \
1818                                                                    \
1819         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args);      \
1820                                                                    \
1821         return ret;                                                    \
1822 }
1823
1824 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1825 JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
1826 JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
1827 JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
1828 JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
1829 JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
1830 JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
1831 JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
1832
1833
1834 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
1835 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
1836                                                                  jmethodID methodID,           \
1837                                                                  const jvalue *args)           \
1838 {                                                              \
1839         java_handle_t *o;                                          \
1840         methodinfo    *m;                                          \
1841         type           ret;                                        \
1842                                                                \
1843         o = (java_handle_t *) obj;                                 \
1844         m = (methodinfo *) methodID;                               \
1845                                                                \
1846         ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1847                                                                \
1848         return ret;                                                \
1849 }
1850
1851 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1852 JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
1853 JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
1854 JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
1855 JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
1856 JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
1857 JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
1858 JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
1859
1860
1861 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1862                                                                  ...)
1863 {
1864         java_handle_t *o;
1865         methodinfo    *m;
1866         java_handle_t *ret;
1867         va_list        ap;
1868
1869         o = (java_handle_t *) obj;
1870         m = (methodinfo *) methodID;
1871
1872         va_start(ap, methodID);
1873         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1874         va_end(ap);
1875
1876         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1877 }
1878
1879
1880 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1881                                                                   va_list args)
1882 {
1883         java_handle_t *o;
1884         methodinfo    *m;
1885         java_handle_t *ret;
1886
1887         o = (java_handle_t *) obj;
1888         m = (methodinfo *) methodID;
1889
1890         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1891
1892         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1893 }
1894
1895
1896 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1897                                                                   const jvalue *args)
1898 {
1899         java_handle_t *o;
1900         methodinfo    *m;
1901         java_handle_t *ret;
1902
1903         o = (java_handle_t *) obj;
1904         m = (methodinfo *) methodID;
1905
1906         ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1907
1908         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1909 }
1910
1911
1912
1913 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1914 {
1915         java_handle_t *o;
1916         methodinfo    *m;
1917         va_list        ap;
1918
1919         o = (java_handle_t *) obj;
1920         m = (methodinfo *) methodID;
1921
1922         va_start(ap, methodID);
1923         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1924         va_end(ap);
1925 }
1926
1927
1928 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1929                                                          va_list args)
1930 {
1931         java_handle_t *o;
1932         methodinfo    *m;
1933
1934         o = (java_handle_t *) obj;
1935         m = (methodinfo *) methodID;
1936
1937         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1938 }
1939
1940
1941 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1942                                                          const jvalue *args)
1943 {
1944         java_handle_t *o;
1945         methodinfo    *m;
1946
1947         o = (java_handle_t *) obj;
1948         m = (methodinfo *) methodID;
1949
1950         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1951 }
1952
1953
1954
1955 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
1956 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
1957                                                                                   jclass clazz, jmethodID methodID, \
1958                                                                                   ...)                              \
1959 {                                                                           \
1960         java_handle_t *o;                                                       \
1961         classinfo     *c;                                                       \
1962         methodinfo    *m;                                                       \
1963         va_list        ap;                                                      \
1964         type           ret;                                                     \
1965                                                                             \
1966         o = (java_handle_t *) obj;                                              \
1967         c = LLNI_classinfo_unwrap(clazz);                                       \
1968         m = (methodinfo *) methodID;                                            \
1969                                                                             \
1970         va_start(ap, methodID);                                                 \
1971         ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
1972         va_end(ap);                                                             \
1973                                                                             \
1974         return ret;                                                             \
1975 }
1976
1977 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1978 JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
1979 JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
1980 JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
1981 JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
1982 JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
1983 JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
1984 JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
1985
1986
1987 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
1988 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
1989                                                                                    jclass clazz, jmethodID methodID, \
1990                                                                                    va_list args)                     \
1991 {                                                                            \
1992         java_handle_t *o;                                                        \
1993         classinfo     *c;                                                        \
1994         methodinfo    *m;                                                        \
1995         type           ret;                                                      \
1996                                                                              \
1997         o = (java_handle_t *) obj;                                               \
1998         c = LLNI_classinfo_unwrap(clazz);                                        \
1999         m = (methodinfo *) methodID;                                             \
2000                                                                              \
2001         ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
2002                                                                              \
2003         return ret;                                                              \
2004 }
2005
2006 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
2007 JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
2008 JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
2009 JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
2010 JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
2011 JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
2012 JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
2013 JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
2014
2015
2016 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
2017 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
2018                                                                                    jclass clazz, jmethodID methodID, \
2019                                                                                    const jvalue *args)               \
2020 {                                                                            \
2021         log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
2022                                                                              \
2023         return 0;                                                                \
2024 }
2025
2026 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
2027 JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
2028 JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
2029 JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
2030 JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
2031 JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
2032 JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
2033 JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
2034
2035 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
2036                                                                                    jclass clazz, jmethodID methodID,
2037                                                                                    ...)
2038 {
2039         java_handle_t *o;
2040         classinfo     *c;
2041         methodinfo    *m;
2042         java_handle_t *r;
2043         va_list        ap;
2044
2045         o = (java_handle_t *) obj;
2046         c = LLNI_classinfo_unwrap(clazz);
2047         m = (methodinfo *) methodID;
2048
2049         va_start(ap, methodID);
2050         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2051         va_end(ap);
2052
2053         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2054 }
2055
2056
2057 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
2058                                                                                         jclass clazz, jmethodID methodID,
2059                                                                                         va_list args)
2060 {
2061         java_handle_t *o;
2062         classinfo     *c;
2063         methodinfo    *m;
2064         java_handle_t *r;
2065
2066         o = (java_handle_t *) obj;
2067         c = LLNI_classinfo_unwrap(clazz);
2068         m = (methodinfo *) methodID;
2069
2070         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2071
2072         return _Jv_JNI_NewLocalRef(env, (jobject) r);
2073 }
2074
2075
2076 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2077                                                                                         jclass clazz, jmethodID methodID,
2078                                                                                         const jvalue *args)
2079 {
2080         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2081
2082         return _Jv_JNI_NewLocalRef(env, NULL);
2083 }
2084
2085
2086 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2087                                                                           jmethodID methodID, ...)
2088 {
2089         java_handle_t *o;
2090         classinfo     *c;
2091         methodinfo    *m;
2092         va_list        ap;
2093
2094         o = (java_handle_t *) obj;
2095         c = LLNI_classinfo_unwrap(clazz);
2096         m = (methodinfo *) methodID;
2097
2098         va_start(ap, methodID);
2099         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2100         va_end(ap);
2101 }
2102
2103
2104 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2105                                                                            jmethodID methodID, va_list args)
2106 {
2107         java_handle_t *o;
2108         classinfo     *c;
2109         methodinfo    *m;
2110
2111         o = (java_handle_t *) obj;
2112         c = LLNI_classinfo_unwrap(clazz);
2113         m = (methodinfo *) methodID;
2114
2115         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2116 }
2117
2118
2119 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2120                                                                            jmethodID methodID, const jvalue * args)
2121 {       
2122         java_handle_t *o;
2123         classinfo     *c;
2124         methodinfo    *m;
2125
2126         o = (java_handle_t *) obj;
2127         c = LLNI_classinfo_unwrap(clazz);
2128         m = (methodinfo *) methodID;
2129
2130         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2131 }
2132
2133
2134 /* Accessing Fields of Objects ************************************************/
2135
2136 /* GetFieldID ******************************************************************
2137
2138    Returns the field ID for an instance (nonstatic) field of a
2139    class. The field is specified by its name and signature. The
2140    Get<type>Field and Set<type>Field families of accessor functions
2141    use field IDs to retrieve object fields.
2142
2143 *******************************************************************************/
2144
2145 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2146                                                         const char *sig)
2147 {
2148         classinfo *c;
2149         fieldinfo *f;
2150         utf       *uname;
2151         utf       *udesc;
2152
2153         STATISTICS(jniinvokation());
2154
2155         c = LLNI_classinfo_unwrap(clazz);
2156
2157         /* XXX NPE check? */
2158
2159         uname = utf_new_char((char *) name);
2160         udesc = utf_new_char((char *) sig);
2161
2162         f = class_findfield(c, uname, udesc); 
2163         
2164         if (f == NULL)
2165                 exceptions_throw_nosuchfielderror(c, uname);  
2166
2167         return (jfieldID) f;
2168 }
2169
2170
2171 /* Get<type>Field Routines *****************************************************
2172
2173    This family of accessor routines returns the value of an instance
2174    (nonstatic) field of an object. The field to access is specified by
2175    a field ID obtained by calling GetFieldID().
2176
2177 *******************************************************************************/
2178
2179 #define JNI_GET_FIELD(name, type, intern)                                 \
2180 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2181 {                                                                         \
2182         intern ret;                                                           \
2183                                                                           \
2184         STATISTICS(jniinvokation());                                          \
2185                                                                           \
2186         ret = GET_FIELD(obj, intern, fieldID);                                \
2187                                                                           \
2188         return (type) ret;                                                    \
2189 }
2190
2191 JNI_GET_FIELD(Boolean, jboolean, s4)
2192 JNI_GET_FIELD(Byte,    jbyte,    s4)
2193 JNI_GET_FIELD(Char,    jchar,    s4)
2194 JNI_GET_FIELD(Short,   jshort,   s4)
2195 JNI_GET_FIELD(Int,     jint,     s4)
2196 JNI_GET_FIELD(Long,    jlong,    s8)
2197 JNI_GET_FIELD(Float,   jfloat,   float)
2198 JNI_GET_FIELD(Double,  jdouble,  double)
2199
2200
2201 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2202 {
2203         java_handle_t *o;
2204
2205         STATISTICS(jniinvokation());
2206
2207         vm_abort("this needs to be fixed");
2208         o = GET_FIELD(obj, java_handle_t*, fieldID);
2209
2210         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2211 }
2212
2213
2214 /* Set<type>Field Routines *****************************************************
2215
2216    This family of accessor routines sets the value of an instance
2217    (nonstatic) field of an object. The field to access is specified by
2218    a field ID obtained by calling GetFieldID().
2219
2220 *******************************************************************************/
2221
2222 #define JNI_SET_FIELD(name, type, intern)                                 \
2223 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2224                                                           type value)                                 \
2225 {                                                                         \
2226         STATISTICS(jniinvokation());                                          \
2227                                                                           \
2228         SET_FIELD(obj, intern, fieldID, value);                               \
2229 }
2230
2231 JNI_SET_FIELD(Boolean, jboolean, s4)
2232 JNI_SET_FIELD(Byte,    jbyte,    s4)
2233 JNI_SET_FIELD(Char,    jchar,    s4)
2234 JNI_SET_FIELD(Short,   jshort,   s4)
2235 JNI_SET_FIELD(Int,     jint,     s4)
2236 JNI_SET_FIELD(Long,    jlong,    s8)
2237 JNI_SET_FIELD(Float,   jfloat,   float)
2238 JNI_SET_FIELD(Double,  jdouble,  double)
2239
2240
2241 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2242                                                         jobject value)
2243 {
2244         STATISTICS(jniinvokation());
2245
2246         vm_abort("this needs to be fixed");
2247         SET_FIELD(obj, java_handle_t*, fieldID, value);
2248 }
2249
2250
2251 /* Calling Static Methods *****************************************************/
2252
2253 /* GetStaticMethodID ***********************************************************
2254
2255    Returns the method ID for a static method of a class. The method is
2256    specified by its name and signature.
2257
2258    GetStaticMethodID() causes an uninitialized class to be
2259    initialized.
2260
2261 *******************************************************************************/
2262
2263 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2264                                                                         const char *sig)
2265 {
2266         classinfo  *c;
2267         utf        *uname;
2268         utf        *udesc;
2269         methodinfo *m;
2270
2271         TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
2272
2273         c = LLNI_classinfo_unwrap(clazz);
2274
2275         if (c == NULL)
2276                 return NULL;
2277
2278         if (!(c->state & CLASS_INITIALIZED))
2279                 if (!initialize_class(c))
2280                         return NULL;
2281
2282         /* try to get the static method of the class */
2283
2284         uname = utf_new_char((char *) name);
2285         udesc = utf_new_char((char *) sig);
2286
2287         m = class_resolvemethod(c, uname, udesc);
2288
2289         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2290                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2291
2292                 return NULL;
2293         }
2294
2295         return (jmethodID) m;
2296 }
2297
2298
2299 #define JNI_CALL_STATIC_METHOD(name, type, intern)               \
2300 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2301                                                                           jmethodID methodID, ...)   \
2302 {                                                                \
2303         methodinfo *m;                                               \
2304         va_list     ap;                                              \
2305         type        res;                                             \
2306                                                                  \
2307         m = (methodinfo *) methodID;                                 \
2308                                                                  \
2309         va_start(ap, methodID);                                      \
2310         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
2311         va_end(ap);                                                  \
2312                                                                  \
2313         return res;                                                  \
2314 }
2315
2316 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2317 JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
2318 JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
2319 JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
2320 JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
2321 JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
2322 JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
2323 JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
2324
2325
2326 #define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
2327 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
2328                                                                            jmethodID methodID, va_list args) \
2329 {                                                                        \
2330         methodinfo *m;                                                       \
2331         type        res;                                                     \
2332                                                                          \
2333         m = (methodinfo *) methodID;                                         \
2334                                                                          \
2335         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
2336                                                                          \
2337         return res;                                                          \
2338 }
2339
2340 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2341 JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
2342 JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
2343 JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
2344 JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
2345 JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
2346 JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
2347 JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
2348
2349
2350 #define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
2351 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
2352                                                                            jmethodID methodID, const jvalue *args) \
2353 {                                                                              \
2354         methodinfo *m;                                                             \
2355         type        res;                                                           \
2356                                                                                \
2357         m = (methodinfo *) methodID;                                               \
2358                                                                                \
2359         res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
2360                                                                                \
2361         return res;                                                                \
2362 }
2363
2364 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2365 JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
2366 JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
2367 JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
2368 JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
2369 JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
2370 JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
2371 JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
2372
2373
2374 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2375                                                                            jmethodID methodID, ...)
2376 {
2377         methodinfo    *m;
2378         java_handle_t *o;
2379         va_list        ap;
2380
2381         m = (methodinfo *) methodID;
2382
2383         va_start(ap, methodID);
2384         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2385         va_end(ap);
2386
2387         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2388 }
2389
2390
2391 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2392                                                                                 jmethodID methodID, va_list args)
2393 {
2394         methodinfo    *m;
2395         java_handle_t *o;
2396
2397         m = (methodinfo *) methodID;
2398
2399         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2400
2401         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2402 }
2403
2404
2405 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2406                                                                                 jmethodID methodID, const jvalue *args)
2407 {
2408         methodinfo    *m;
2409         java_handle_t *o;
2410
2411         m = (methodinfo *) methodID;
2412
2413         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2414
2415         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2416 }
2417
2418
2419 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2420                                                                   jmethodID methodID, ...)
2421 {
2422         methodinfo *m;
2423         va_list     ap;
2424
2425         m = (methodinfo *) methodID;
2426
2427         va_start(ap, methodID);
2428         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2429         va_end(ap);
2430 }
2431
2432
2433 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2434                                                                    jmethodID methodID, va_list args)
2435 {
2436         methodinfo *m;
2437
2438         m = (methodinfo *) methodID;
2439
2440         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2441 }
2442
2443
2444 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2445                                                                    jmethodID methodID, const jvalue * args)
2446 {
2447         methodinfo *m;
2448
2449         m = (methodinfo *) methodID;
2450
2451         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2452 }
2453
2454
2455 /* Accessing Static Fields ****************************************************/
2456
2457 /* GetStaticFieldID ************************************************************
2458
2459    Returns the field ID for a static field of a class. The field is
2460    specified by its name and signature. The GetStatic<type>Field and
2461    SetStatic<type>Field families of accessor functions use field IDs
2462    to retrieve static fields.
2463
2464 *******************************************************************************/
2465
2466 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2467                                                                   const char *sig)
2468 {
2469         classinfo *c;
2470         fieldinfo *f;
2471         utf       *uname;
2472         utf       *usig;
2473
2474         STATISTICS(jniinvokation());
2475
2476         c = LLNI_classinfo_unwrap(clazz);
2477
2478         uname = utf_new_char((char *) name);
2479         usig  = utf_new_char((char *) sig);
2480
2481         f = class_findfield(c, uname, usig);
2482         
2483         if (f == NULL)
2484                 exceptions_throw_nosuchfielderror(c, uname);
2485
2486         return (jfieldID) f;
2487 }
2488
2489
2490 /* GetStatic<type>Field ********************************************************
2491
2492    This family of accessor routines returns the value of a static
2493    field of an object.
2494
2495 *******************************************************************************/
2496
2497 #define JNI_GET_STATIC_FIELD(name, type, field)                \
2498 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2499                                                                         jfieldID fieldID)          \
2500 {                                                              \
2501         classinfo *c;                                              \
2502         fieldinfo *f;                                              \
2503                                                                \
2504         STATISTICS(jniinvokation());                               \
2505                                                                \
2506         c = LLNI_classinfo_unwrap(clazz);                          \
2507         f = (fieldinfo *) fieldID;                                 \
2508                                                                \
2509         if (!(c->state & CLASS_INITIALIZED))                       \
2510                 if (!initialize_class(c))                              \
2511                         return 0;                                          \
2512                                                                \
2513         return f->value->field;                                    \
2514 }
2515
2516 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2517 JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
2518 JNI_GET_STATIC_FIELD(Char,    jchar,    i)
2519 JNI_GET_STATIC_FIELD(Short,   jshort,   i)
2520 JNI_GET_STATIC_FIELD(Int,     jint,     i)
2521 JNI_GET_STATIC_FIELD(Long,    jlong,    l)
2522 JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
2523 JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
2524
2525
2526 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2527                                                                          jfieldID fieldID)
2528 {
2529         classinfo *c;
2530         fieldinfo *f;
2531
2532         STATISTICS(jniinvokation());
2533
2534         c = LLNI_classinfo_unwrap(clazz);
2535         f = (fieldinfo *) fieldID;
2536
2537         if (!(c->state & CLASS_INITIALIZED))
2538                 if (!initialize_class(c))
2539                         return NULL;
2540
2541         return _Jv_JNI_NewLocalRef(env, f->value->a);
2542 }
2543
2544
2545 /*  SetStatic<type>Field *******************************************************
2546
2547         This family of accessor routines sets the value of a static field
2548         of an object.
2549
2550 *******************************************************************************/
2551
2552 #define JNI_SET_STATIC_FIELD(name, type, field)                \
2553 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2554                                                                         jfieldID fieldID,          \
2555                                                                         type value)                \
2556 {                                                              \
2557         classinfo *c;                                              \
2558         fieldinfo *f;                                              \
2559                                                                \
2560         STATISTICS(jniinvokation());                               \
2561                                                                \
2562         c = LLNI_classinfo_unwrap(clazz);                          \
2563         f = (fieldinfo *) fieldID;                                 \
2564                                                                \
2565         if (!(c->state & CLASS_INITIALIZED))                       \
2566                 if (!initialize_class(c))                              \
2567                         return;                                            \
2568                                                                \
2569         f->value->field = value;                                   \
2570 }
2571
2572 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2573 JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
2574 JNI_SET_STATIC_FIELD(Char,    jchar,    i)
2575 JNI_SET_STATIC_FIELD(Short,   jshort,   i)
2576 JNI_SET_STATIC_FIELD(Int,     jint,     i)
2577 JNI_SET_STATIC_FIELD(Long,    jlong,    l)
2578 JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
2579 JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
2580
2581
2582 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2583                                                                   jobject value)
2584 {
2585         classinfo *c;
2586         fieldinfo *f;
2587
2588         STATISTICS(jniinvokation());
2589
2590         c = LLNI_classinfo_unwrap(clazz);
2591         f = (fieldinfo *) fieldID;
2592
2593         if (!(c->state & CLASS_INITIALIZED))
2594                 if (!initialize_class(c))
2595                         return;
2596
2597         f->value->a = value;
2598 }
2599
2600
2601 /* String Operations **********************************************************/
2602
2603 /* NewString *******************************************************************
2604
2605    Create new java.lang.String object from an array of Unicode
2606    characters.
2607
2608 *******************************************************************************/
2609
2610 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2611 {
2612         java_lang_String        *s;
2613         java_handle_chararray_t *a;
2614         u4                       i;
2615
2616         STATISTICS(jniinvokation());
2617         
2618         s = (java_lang_String *) builtin_new(class_java_lang_String);
2619         a = builtin_newarray_char(len);
2620
2621         /* javastring or characterarray could not be created */
2622         if ((a == NULL) || (s == NULL))
2623                 return NULL;
2624
2625         /* copy text */
2626         for (i = 0; i < len; i++)
2627                 LLNI_array_direct(a, i) = buf[i];
2628
2629         LLNI_field_set_ref(s, value , a);
2630         LLNI_field_set_val(s, offset, 0);
2631         LLNI_field_set_val(s, count , len);
2632
2633         return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2634 }
2635
2636
2637 static jchar emptyStringJ[]={0,0};
2638
2639 /* GetStringLength *************************************************************
2640
2641    Returns the length (the count of Unicode characters) of a Java
2642    string.
2643
2644 *******************************************************************************/
2645
2646 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2647 {
2648         java_lang_String *s;
2649         jsize             len;
2650
2651         TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
2652
2653         s = (java_lang_String *) str;
2654
2655         LLNI_field_get_val(s, count, len);
2656
2657         return len;
2658 }
2659
2660
2661 /********************  convertes javastring to u2-array ****************************/
2662         
2663 u2 *javastring_tou2(jstring so) 
2664 {
2665         java_lang_String        *s;
2666         java_handle_chararray_t *a;
2667         u2                      *stringbuffer;
2668         u4                       i;
2669         int32_t                  count;
2670         int32_t                  offset;
2671
2672         STATISTICS(jniinvokation());
2673         
2674         s = (java_lang_String *) so;
2675
2676         if (!s)
2677                 return NULL;
2678
2679         LLNI_field_get_ref(s, value, a);
2680
2681         if (!a)
2682                 return NULL;
2683
2684         LLNI_field_get_val(s, count, count);
2685         LLNI_field_get_val(s, offset, offset);
2686
2687         /* allocate memory */
2688
2689         stringbuffer = MNEW(u2, count + 1);
2690
2691         /* copy text */
2692
2693         for (i = 0; i < count; i++)
2694                 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2695         
2696         /* terminate string */
2697
2698         stringbuffer[i] = '\0';
2699
2700         return stringbuffer;
2701 }
2702
2703
2704 /* GetStringChars **************************************************************
2705
2706    Returns a pointer to the array of Unicode characters of the
2707    string. This pointer is valid until ReleaseStringChars() is called.
2708
2709 *******************************************************************************/
2710
2711 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2712 {       
2713         jchar *jc;
2714
2715         STATISTICS(jniinvokation());
2716
2717         jc = javastring_tou2(str);
2718
2719         if (jc) {
2720                 if (isCopy)
2721                         *isCopy = JNI_TRUE;
2722
2723                 return jc;
2724         }
2725
2726         if (isCopy)
2727                 *isCopy = JNI_TRUE;
2728
2729         return emptyStringJ;
2730 }
2731
2732
2733 /* ReleaseStringChars **********************************************************
2734
2735    Informs the VM that the native code no longer needs access to
2736    chars. The chars argument is a pointer obtained from string using
2737    GetStringChars().
2738
2739 *******************************************************************************/
2740
2741 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2742 {
2743         java_lang_String *s;
2744
2745         STATISTICS(jniinvokation());
2746
2747         if (chars == emptyStringJ)
2748                 return;
2749
2750         s = (java_lang_String *) str;
2751
2752         MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2753 }
2754
2755
2756 /* NewStringUTF ****************************************************************
2757
2758    Constructs a new java.lang.String object from an array of UTF-8
2759    characters.
2760
2761 *******************************************************************************/
2762
2763 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2764 {
2765         java_lang_String *s;
2766
2767         TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
2768
2769         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2770
2771     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2772 }
2773
2774
2775 /****************** returns the utf8 length in bytes of a string *******************/
2776
2777 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2778 {   
2779         java_lang_String *s;
2780         s4                length;
2781
2782         TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
2783
2784         s = (java_lang_String *) string;
2785
2786         length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2787
2788         return length;
2789 }
2790
2791
2792 /* GetStringUTFChars ***********************************************************
2793
2794    Returns a pointer to an array of UTF-8 characters of the
2795    string. This array is valid until it is released by
2796    ReleaseStringUTFChars().
2797
2798 *******************************************************************************/
2799
2800 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2801                                                                           jboolean *isCopy)
2802 {
2803         utf *u;
2804
2805         STATISTICS(jniinvokation());
2806
2807         if (string == NULL)
2808                 return "";
2809
2810         if (isCopy)
2811                 *isCopy = JNI_TRUE;
2812         
2813         u = javastring_toutf((java_handle_t *) string, false);
2814
2815         if (u != NULL)
2816                 return u->text;
2817
2818         return "";
2819 }
2820
2821
2822 /* ReleaseStringUTFChars *******************************************************
2823
2824    Informs the VM that the native code no longer needs access to
2825    utf. The utf argument is a pointer derived from string using
2826    GetStringUTFChars().
2827
2828 *******************************************************************************/
2829
2830 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2831 {
2832         STATISTICS(jniinvokation());
2833
2834     /* XXX we don't release utf chars right now, perhaps that should be done 
2835            later. Since there is always one reference the garbage collector will
2836            never get them */
2837 }
2838
2839
2840 /* Array Operations ***********************************************************/
2841
2842 /* GetArrayLength **************************************************************
2843
2844    Returns the number of elements in the array.
2845
2846 *******************************************************************************/
2847
2848 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2849 {
2850         java_handle_t *a;
2851         jsize          size;
2852
2853         STATISTICS(jniinvokation());
2854
2855         a = (java_handle_t *) array;
2856
2857         size = LLNI_array_size(a);
2858
2859         return size;
2860 }
2861
2862
2863 /* NewObjectArray **************************************************************
2864
2865    Constructs a new array holding objects in class elementClass. All
2866    elements are initially set to initialElement.
2867
2868 *******************************************************************************/
2869
2870 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2871                                                                         jclass elementClass, jobject initialElement)
2872 {
2873         classinfo                 *c;
2874         java_handle_t             *o;
2875         java_handle_objectarray_t *oa;
2876         s4                         i;
2877
2878         STATISTICS(jniinvokation());
2879
2880         c = LLNI_classinfo_unwrap(elementClass);
2881         o = (java_handle_t *) initialElement;
2882
2883         if (length < 0) {
2884                 exceptions_throw_negativearraysizeexception();
2885                 return NULL;
2886         }
2887
2888     oa = builtin_anewarray(length, c);
2889
2890         if (oa == NULL)
2891                 return NULL;
2892
2893         /* set all elements to initialElement */
2894
2895         for (i = 0; i < length; i++)
2896                 LLNI_objectarray_element_set(oa, i, o);
2897
2898         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2899 }
2900
2901
2902 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2903                                                                           jsize index)
2904 {
2905         java_handle_objectarray_t *oa;
2906         java_handle_t             *o;
2907
2908         STATISTICS(jniinvokation());
2909
2910         oa = (java_handle_objectarray_t *) array;
2911
2912         if (index >= LLNI_array_size(oa)) {
2913                 exceptions_throw_arrayindexoutofboundsexception();
2914                 return NULL;
2915         }
2916
2917         LLNI_objectarray_element_get(oa, index, o);
2918
2919         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2920 }
2921
2922
2923 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2924                                                                    jsize index, jobject val)
2925 {
2926         java_handle_objectarray_t *oa;
2927         java_handle_t             *o;
2928
2929         STATISTICS(jniinvokation());
2930
2931         oa = (java_handle_objectarray_t *) array;
2932         o  = (java_handle_t *) val;
2933
2934         if (index >= LLNI_array_size(oa)) {
2935                 exceptions_throw_arrayindexoutofboundsexception();
2936                 return;
2937         }
2938
2939         /* check if the class of value is a subclass of the element class
2940            of the array */
2941
2942         if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
2943                 return;
2944
2945         LLNI_objectarray_element_set(oa, index, o);
2946 }
2947
2948
2949 #define JNI_NEW_ARRAY(name, type, intern)                \
2950 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
2951 {                                                        \
2952         java_handle_##intern##array_t *a;                    \
2953                                                          \
2954         STATISTICS(jniinvokation());                         \
2955                                                          \
2956         if (len < 0) {                                       \
2957                 exceptions_throw_negativearraysizeexception();   \
2958                 return NULL;                                     \
2959         }                                                    \
2960                                                          \
2961         a = builtin_newarray_##intern(len);                  \
2962                                                          \
2963         return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2964 }
2965
2966 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2967 JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
2968 JNI_NEW_ARRAY(Char,    jcharArray,    char)
2969 JNI_NEW_ARRAY(Short,   jshortArray,   byte)
2970 JNI_NEW_ARRAY(Int,     jintArray,     int)
2971 JNI_NEW_ARRAY(Long,    jlongArray,    long)
2972 JNI_NEW_ARRAY(Float,   jfloatArray,   float)
2973 JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
2974
2975
2976 /* Get<PrimitiveType>ArrayElements *********************************************
2977
2978    A family of functions that returns the body of the primitive array.
2979
2980 *******************************************************************************/
2981
2982 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
2983 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2984                                                                                  jboolean *isCopy)             \
2985 {                                                                      \
2986         java_handle_##intern##array_t *a;                                  \
2987                                                                        \
2988         STATISTICS(jniinvokation());                                       \
2989                                                                        \
2990         a = (java_handle_##intern##array_t *) array;                       \
2991                                                                        \
2992         if (isCopy)                                                        \
2993                 *isCopy = JNI_FALSE;                                           \
2994                                                                        \
2995         return LLNI_array_data(a);                                         \
2996 }
2997
2998 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2999 JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
3000 JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
3001 JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
3002 JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
3003 JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
3004 JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
3005 JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
3006
3007
3008 /* Release<PrimitiveType>ArrayElements *****************************************
3009
3010    A family of functions that informs the VM that the native code no
3011    longer needs access to elems. The elems argument is a pointer
3012    derived from array using the corresponding
3013    Get<PrimitiveType>ArrayElements() function. If necessary, this
3014    function copies back all changes made to elems to the original
3015    array.
3016
3017 *******************************************************************************/
3018
3019 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
3020 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
3021                                                                                   type *elems, jint mode)          \
3022 {                                                                          \
3023         java_handle_##intern##array_t *a;                                      \
3024                                                                            \
3025         STATISTICS(jniinvokation());                                           \
3026                                                                            \
3027         a = (java_handle_##intern##array_t *) array;                           \
3028                                                                            \
3029         if (elems != LLNI_array_data(a)) {                                     \
3030                 switch (mode) {                                                    \
3031                 case JNI_COMMIT:                                                   \
3032                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3033                         break;                                                         \
3034                 case 0:                                                            \
3035                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3036                         /* XXX TWISTI how should it be freed? */                       \
3037                         break;                                                         \
3038                 case JNI_ABORT:                                                    \
3039                         /* XXX TWISTI how should it be freed? */                       \
3040                         break;                                                         \
3041                 }                                                                  \
3042         }                                                                      \
3043 }
3044
3045 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3046 JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
3047 JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
3048 JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
3049 JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
3050 JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
3051 JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
3052 JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
3053
3054
3055 /*  Get<PrimitiveType>ArrayRegion **********************************************
3056
3057         A family of functions that copies a region of a primitive array
3058         into a buffer.
3059
3060 *******************************************************************************/
3061
3062 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
3063 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
3064                                                                         jsize start, jsize len, type *buf)  \
3065 {                                                                       \
3066         java_handle_##intern##array_t *a;                                   \
3067                                                                         \
3068         STATISTICS(jniinvokation());                                        \
3069                                                                         \
3070         a = (java_handle_##intern##array_t *) array;                        \
3071                                                                         \
3072         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3073                 exceptions_throw_arrayindexoutofboundsexception();              \
3074         else                                                                \
3075                 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
3076 }
3077
3078 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3079 JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3080 JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
3081 JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
3082 JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
3083 JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
3084 JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
3085 JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
3086
3087
3088 /*  Set<PrimitiveType>ArrayRegion **********************************************
3089
3090         A family of functions that copies back a region of a primitive
3091         array from a buffer.
3092
3093 *******************************************************************************/
3094
3095 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
3096 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
3097                                                                         jsize start, jsize len, const type *buf) \
3098 {                                                                            \
3099         java_handle_##intern##array_t *a;                                        \
3100                                                                              \
3101         STATISTICS(jniinvokation());                                             \
3102                                                                              \
3103         a = (java_handle_##intern##array_t *) array;                             \
3104                                                                              \
3105         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
3106                 exceptions_throw_arrayindexoutofboundsexception();                   \
3107         else                                                                     \
3108                 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
3109 }
3110
3111 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3112 JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3113 JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
3114 JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
3115 JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
3116 JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
3117 JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
3118 JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
3119
3120
3121 /* Registering Native Methods *************************************************/
3122
3123 /* RegisterNatives *************************************************************
3124
3125    Registers native methods with the class specified by the clazz
3126    argument. The methods parameter specifies an array of
3127    JNINativeMethod structures that contain the names, signatures, and
3128    function pointers of the native methods. The nMethods parameter
3129    specifies the number of native methods in the array.
3130
3131 *******************************************************************************/
3132
3133 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3134                                                          const JNINativeMethod *methods, jint nMethods)
3135 {
3136         classinfo *c;
3137
3138         STATISTICS(jniinvokation());
3139
3140         c = LLNI_classinfo_unwrap(clazz);
3141
3142         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3143         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
3144         */
3145
3146         native_method_register(c->name, methods, nMethods);
3147
3148     return 0;
3149 }
3150
3151
3152 /* UnregisterNatives ***********************************************************
3153
3154    Unregisters native methods of a class. The class goes back to the
3155    state before it was linked or registered with its native method
3156    functions.
3157
3158    This function should not be used in normal native code. Instead, it
3159    provides special programs a way to reload and relink native
3160    libraries.
3161
3162 *******************************************************************************/
3163
3164 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3165 {
3166         STATISTICS(jniinvokation());
3167
3168         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3169
3170     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3171
3172     return 0;
3173 }
3174
3175
3176 /* Monitor Operations *********************************************************/
3177
3178 /* MonitorEnter ****************************************************************
3179
3180    Enters the monitor associated with the underlying Java object
3181    referred to by obj.
3182
3183 *******************************************************************************/
3184
3185 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3186 {
3187         STATISTICS(jniinvokation());
3188
3189         if (obj == NULL) {
3190                 exceptions_throw_nullpointerexception();
3191                 return JNI_ERR;
3192         }
3193
3194         LOCK_MONITOR_ENTER(obj);
3195
3196         return JNI_OK;
3197 }
3198
3199
3200 /* MonitorExit *****************************************************************
3201
3202    The current thread must be the owner of the monitor associated with
3203    the underlying Java object referred to by obj. The thread
3204    decrements the counter indicating the number of times it has
3205    entered this monitor. If the value of the counter becomes zero, the
3206    current thread releases the monitor.
3207
3208 *******************************************************************************/
3209
3210 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3211 {
3212         STATISTICS(jniinvokation());
3213
3214         if (obj == NULL) {
3215                 exceptions_throw_nullpointerexception();
3216                 return JNI_ERR;
3217         }
3218
3219         LOCK_MONITOR_EXIT(obj);
3220
3221         return JNI_OK;
3222 }
3223
3224
3225 /* JavaVM Interface ***********************************************************/
3226
3227 /* GetJavaVM *******************************************************************
3228
3229    Returns the Java VM interface (used in the Invocation API)
3230    associated with the current thread. The result is placed at the
3231    location pointed to by the second argument, vm.
3232
3233 *******************************************************************************/
3234
3235 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3236 {
3237         STATISTICS(jniinvokation());
3238
3239     *vm = (JavaVM *) _Jv_jvm;
3240
3241         return 0;
3242 }
3243
3244
3245 /* GetStringRegion *************************************************************
3246
3247    Copies len number of Unicode characters beginning at offset start
3248    to the given buffer buf.
3249
3250    Throws StringIndexOutOfBoundsException on index overflow.
3251
3252 *******************************************************************************/
3253
3254 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3255                                                          jchar *buf)
3256 {
3257         java_lang_String        *s;
3258         java_handle_chararray_t *ca;
3259
3260         STATISTICS(jniinvokation());
3261
3262         s  = (java_lang_String *) str;
3263         LLNI_field_get_ref(s, value, ca);
3264
3265         if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3266                 (start + len > LLNI_field_direct(s, count))) {
3267                 exceptions_throw_stringindexoutofboundsexception();
3268                 return;
3269         }
3270
3271         MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3272 }
3273
3274
3275 /* GetStringUTFRegion **********************************************************
3276
3277     Translates len number of Unicode characters beginning at offset
3278     start into UTF-8 format and place the result in the given buffer
3279     buf.
3280
3281     Throws StringIndexOutOfBoundsException on index overflow. 
3282
3283 *******************************************************************************/
3284
3285 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3286                                                                 jsize len, char *buf)
3287 {
3288         java_lang_String        *s;
3289         java_handle_chararray_t *ca;
3290         s4                       i;
3291         int32_t                  count;
3292         int32_t                  offset;
3293
3294         TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
3295
3296         s  = (java_lang_String *) str;
3297         LLNI_field_get_ref(s, value, ca);
3298         LLNI_field_get_val(s, count, count);
3299         LLNI_field_get_val(s, offset, offset);
3300
3301         if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3302                 exceptions_throw_stringindexoutofboundsexception();
3303                 return;
3304         }
3305
3306         for (i = 0; i < len; i++)
3307                 buf[i] = LLNI_array_direct(ca, offset + start + i);
3308
3309         buf[i] = '\0';
3310 }
3311
3312
3313 /* GetPrimitiveArrayCritical ***************************************************
3314
3315    Obtain a direct pointer to array elements.
3316
3317 *******************************************************************************/
3318
3319 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3320                                                                                 jboolean *isCopy)
3321 {
3322         java_handle_bytearray_t *ba;
3323         jbyte                   *bp;
3324
3325         ba = (java_handle_bytearray_t *) array;
3326
3327         /* do the same as Kaffe does */
3328
3329         bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3330
3331         return (void *) bp;
3332 }
3333
3334
3335 /* ReleasePrimitiveArrayCritical ***********************************************
3336
3337    No specific documentation.
3338
3339 *******************************************************************************/
3340
3341 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3342                                                                                    void *carray, jint mode)
3343 {
3344         STATISTICS(jniinvokation());
3345
3346         /* do the same as Kaffe does */
3347
3348         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3349                                                                          mode);
3350 }
3351
3352
3353 /* GetStringCritical ***********************************************************
3354
3355    The semantics of these two functions are similar to the existing
3356    Get/ReleaseStringChars functions.
3357
3358 *******************************************************************************/
3359
3360 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3361                                                                            jboolean *isCopy)
3362 {
3363         STATISTICS(jniinvokation());
3364
3365         return _Jv_JNI_GetStringChars(env, string, isCopy);
3366 }
3367
3368
3369 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3370                                                                    const jchar *cstring)
3371 {
3372         STATISTICS(jniinvokation());
3373
3374         _Jv_JNI_ReleaseStringChars(env, string, cstring);
3375 }
3376
3377
3378 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3379 {
3380         STATISTICS(jniinvokation());
3381
3382         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
3383
3384         return obj;
3385 }
3386
3387
3388 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3389 {
3390         STATISTICS(jniinvokation());
3391
3392         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
3393 }
3394
3395
3396 /* NewGlobalRef ****************************************************************
3397
3398    Creates a new global reference to the object referred to by the obj
3399    argument.
3400
3401 *******************************************************************************/
3402     
3403 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3404 {
3405         hashtable_global_ref_entry *gre;
3406         u4   key;                           /* hashkey                            */
3407         u4   slot;                          /* slot in hashtable                  */
3408         java_handle_t *o;
3409
3410         STATISTICS(jniinvokation());
3411
3412         o = (java_handle_t *) obj;
3413
3414         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3415
3416         LLNI_CRITICAL_START;
3417
3418         /* normally addresses are aligned to 4, 8 or 16 bytes */
3419
3420 #if defined(ENABLE_GC_CACAO)
3421         key  = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3422 #else
3423         key  = ((u4) (ptrint) o) >> 4;             /* align to 16-byte boundaries */
3424 #endif
3425         slot = key & (hashtable_global_ref->size - 1);
3426         gre  = hashtable_global_ref->ptr[slot];
3427         
3428         /* search external hash chain for the entry */
3429
3430         while (gre) {
3431                 if (gre->o == LLNI_DIRECT(o)) {
3432                         /* global object found, increment the reference */
3433
3434                         gre->refs++;
3435
3436                         break;
3437                 }
3438
3439                 gre = gre->hashlink;                /* next element in external chain */
3440         }
3441
3442         /* global ref not found, create a new one */
3443
3444         if (gre == NULL) {
3445                 gre = NEW(hashtable_global_ref_entry);
3446
3447 #if defined(ENABLE_GC_CACAO)
3448                 /* register global ref with the GC */
3449
3450                 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3451 #endif
3452
3453                 gre->o    = LLNI_DIRECT(o);
3454                 gre->refs = 1;
3455
3456                 /* insert entry into hashtable */
3457
3458                 gre->hashlink = hashtable_global_ref->ptr[slot];
3459
3460                 hashtable_global_ref->ptr[slot] = gre;
3461
3462                 /* update number of hashtable-entries */
3463
3464                 hashtable_global_ref->entries++;
3465         }
3466
3467         LLNI_CRITICAL_END;
3468
3469         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3470
3471 #if defined(ENABLE_HANDLES)
3472         return gre;
3473 #else
3474         return obj;
3475 #endif
3476 }
3477
3478
3479 /* DeleteGlobalRef *************************************************************
3480
3481    Deletes the global reference pointed to by globalRef.
3482
3483 *******************************************************************************/
3484
3485 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3486 {
3487         hashtable_global_ref_entry *gre;
3488         hashtable_global_ref_entry *prevgre;
3489         u4   key;                           /* hashkey                            */
3490         u4   slot;                          /* slot in hashtable                  */
3491         java_handle_t              *o;
3492
3493         STATISTICS(jniinvokation());
3494
3495         o = (java_handle_t *) globalRef;
3496
3497         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3498
3499         LLNI_CRITICAL_START;
3500
3501         /* normally addresses are aligned to 4, 8 or 16 bytes */
3502
3503 #if defined(ENABLE_GC_CACAO)
3504         key  = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
3505 #else
3506         key  = ((u4) (ptrint) o) >> 4;             /* align to 16-byte boundaries */
3507 #endif
3508         slot = key & (hashtable_global_ref->size - 1);
3509         gre  = hashtable_global_ref->ptr[slot];
3510
3511         /* initialize prevgre */
3512
3513         prevgre = NULL;
3514
3515         /* search external hash chain for the entry */
3516
3517         while (gre) {
3518                 if (gre->o == LLNI_DIRECT(o)) {
3519                         /* global object found, decrement the reference count */
3520
3521                         gre->refs--;
3522
3523                         /* if reference count is 0, remove the entry */
3524
3525                         if (gre->refs == 0) {
3526                                 /* special handling if it's the first in the chain */
3527
3528                                 if (prevgre == NULL)
3529                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
3530                                 else
3531                                         prevgre->hashlink = gre->hashlink;
3532
3533 #if defined(ENABLE_GC_CACAO)
3534                                 /* unregister global ref with the GC */
3535
3536                                 gc_reference_unregister(&(gre->o));
3537 #endif
3538
3539                                 FREE(gre, hashtable_global_ref_entry);
3540                         }
3541
3542                         LLNI_CRITICAL_END;
3543
3544                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3545
3546                         return;
3547                 }
3548
3549                 prevgre = gre;                    /* save current pointer for removal */
3550                 gre     = gre->hashlink;            /* next element in external chain */
3551         }
3552
3553         log_println("JNI-DeleteGlobalRef: global reference not found");
3554
3555         LLNI_CRITICAL_END;
3556
3557         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3558 }
3559
3560
3561 /* ExceptionCheck **************************************************************
3562
3563    Returns JNI_TRUE when there is a pending exception; otherwise,
3564    returns JNI_FALSE.
3565
3566 *******************************************************************************/
3567
3568 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3569 {
3570         java_handle_t *o;
3571
3572         STATISTICS(jniinvokation());
3573
3574         o = exceptions_get_exception();
3575
3576         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3577 }
3578
3579
3580 /* New JNI 1.4 functions ******************************************************/
3581
3582 /* NewDirectByteBuffer *********************************************************
3583
3584    Allocates and returns a direct java.nio.ByteBuffer referring to the
3585    block of memory starting at the memory address address and
3586    extending capacity bytes.
3587
3588 *******************************************************************************/
3589
3590 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3591 {
3592 #if defined(ENABLE_JAVASE)
3593 # if defined(WITH_CLASSPATH_GNU)
3594         java_handle_t           *nbuf;
3595
3596 # if SIZEOF_VOID_P == 8
3597         gnu_classpath_Pointer64 *paddress;
3598 # else
3599         gnu_classpath_Pointer32 *paddress;
3600 # endif
3601
3602         TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3603
3604         /* alocate a gnu.classpath.Pointer{32,64} object */
3605
3606 # if SIZEOF_VOID_P == 8
3607         if (!(paddress = (gnu_classpath_Pointer64 *)
3608                   builtin_new(class_gnu_classpath_Pointer64)))
3609 # else
3610         if (!(paddress = (gnu_classpath_Pointer32 *)
3611                   builtin_new(class_gnu_classpath_Pointer32)))
3612 # endif
3613                 return NULL;
3614
3615         /* fill gnu.classpath.Pointer{32,64} with address */
3616
3617         LLNI_field_set_val(paddress, data, (ptrint) address);
3618
3619         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3620
3621         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3622                                                          (jmethodID) dbbirw_init, NULL, paddress,
3623                                                          (jint) capacity, (jint) capacity, (jint) 0);
3624
3625         /* add local reference and return the value */
3626
3627         return _Jv_JNI_NewLocalRef(env, nbuf);
3628
3629 # elif defined(WITH_CLASSPATH_SUN)
3630
3631         jobject o;
3632         int64_t addr;
3633         int32_t cap;
3634
3635         TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
3636
3637         /* Be paranoid about address sign-extension. */
3638
3639         addr = (int64_t) ((uintptr_t) address);
3640         cap  = (int32_t) capacity;
3641
3642         o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3643                                                   (jmethodID) dbb_init, addr, cap);
3644
3645         /* Add local reference and return the value. */
3646
3647         return _Jv_JNI_NewLocalRef(env, o);
3648
3649 # else
3650 #  error unknown classpath configuration
3651 # endif
3652
3653 #else
3654         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3655
3656         /* keep compiler happy */
3657
3658         return NULL;
3659 #endif
3660 }
3661
3662
3663 /* GetDirectBufferAddress ******************************************************
3664
3665    Fetches and returns the starting address of the memory region
3666    referenced by the given direct java.nio.Buffer.
3667
3668 *******************************************************************************/
3669
3670 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3671 {
3672 #if defined(ENABLE_JAVASE)
3673 # if defined(WITH_CLASSPATH_GNU)
3674
3675         java_nio_DirectByteBufferImpl *nbuf;
3676 #  if SIZEOF_VOID_P == 8
3677         gnu_classpath_Pointer64       *paddress;
3678 #  else
3679         gnu_classpath_Pointer32       *paddress;
3680 #  endif
3681         void                          *address;
3682
3683         TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3684
3685         if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
3686                 return NULL;
3687
3688         nbuf = (java_nio_DirectByteBufferImpl *) buf;
3689
3690 #  if SIZEOF_VOID_P == 8
3691         LLNI_field_get_ref(nbuf, address, paddress);
3692         /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
3693 #  else
3694         LLNI_field_get_ref(nbuf, address, paddress); 
3695         /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
3696 #  endif
3697
3698         if (paddress == NULL)
3699                 return NULL;
3700
3701         LLNI_field_get_val(paddress, data, address);
3702         /* this was the cast to avaoid warning: (void *) paddress->data */
3703
3704         return address;
3705
3706 # elif defined(WITH_CLASSPATH_SUN)
3707
3708         java_nio_Buffer *o;
3709         int64_t          address;
3710         void            *p;
3711
3712         TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
3713
3714         if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
3715                 return NULL;
3716
3717         o = (java_nio_Buffer *) buf;
3718
3719         LLNI_field_get_val(o, address, address);
3720
3721         p = (void *) (intptr_t) address;
3722
3723         return p;
3724
3725 # else
3726 #  error unknown classpath configuration
3727 # endif
3728
3729 #else
3730
3731         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3732
3733         /* keep compiler happy */
3734
3735         return NULL;
3736
3737 #endif
3738 }
3739
3740
3741 /* GetDirectBufferCapacity *****************************************************
3742
3743    Fetches and returns the capacity in bytes of the memory region
3744    referenced by the given direct java.nio.Buffer.
3745
3746 *******************************************************************************/
3747
3748 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3749 {
3750 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3751         java_handle_t   *o;
3752         java_nio_Buffer *nbuf;
3753         jlong            capacity;
3754
3755         STATISTICS(jniinvokation());
3756
3757         o = (java_handle_t *) buf;
3758
3759         if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3760                 return -1;
3761
3762         nbuf = (java_nio_Buffer *) o;
3763
3764         LLNI_field_get_val(nbuf, cap, capacity);
3765
3766         return capacity;
3767 #else
3768         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3769
3770         /* keep compiler happy */
3771
3772         return 0;
3773 #endif
3774 }
3775
3776
3777 /* GetObjectRefType ************************************************************
3778
3779    Returns the type of the object referred to by the obj argument. The
3780    argument obj can either be a local, global or weak global
3781    reference.
3782
3783 *******************************************************************************/
3784
3785 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3786 {
3787         log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3788
3789         return -1;
3790 }
3791
3792
3793 /* DestroyJavaVM ***************************************************************
3794
3795    Unloads a Java VM and reclaims its resources. Only the main thread
3796    can unload the VM. The system waits until the main thread is only
3797    remaining user thread before it destroys the VM.
3798
3799 *******************************************************************************/
3800
3801 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3802 {
3803         int32_t status;
3804
3805         TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
3806
3807     status = vm_destroy(vm);
3808
3809         return status;
3810 }
3811
3812
3813 /* AttachCurrentThread *********************************************************
3814
3815    Attaches the current thread to a Java VM. Returns a JNI interface
3816    pointer in the JNIEnv argument.
3817
3818    Trying to attach a thread that is already attached is a no-op.
3819
3820    A native thread cannot be attached simultaneously to two Java VMs.
3821
3822    When a thread is attached to the VM, the context class loader is
3823    the bootstrap loader.
3824
3825 *******************************************************************************/
3826
3827 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3828 {
3829         JavaVMAttachArgs *vm_aargs;
3830
3831 #if defined(ENABLE_THREADS)
3832         if (threads_get_current_threadobject() == NULL) {
3833                 vm_aargs = (JavaVMAttachArgs *) thr_args;
3834
3835                 if (vm_aargs != NULL) {
3836                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
3837                                 (vm_aargs->version != JNI_VERSION_1_4))
3838                                 return JNI_EVERSION;
3839                 }
3840
3841                 if (!threads_attach_current_thread(vm_aargs, false))
3842                         return JNI_ERR;
3843
3844                 if (!localref_table_init())
3845                         return JNI_ERR;
3846         }
3847 #endif
3848
3849         *p_env = _Jv_env;
3850
3851         return JNI_OK;
3852 }
3853
3854
3855 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3856 {
3857         STATISTICS(jniinvokation());
3858
3859         return jni_attach_current_thread(p_env, thr_args, false);
3860 }
3861
3862
3863 /* DetachCurrentThread *********************************************************
3864
3865    Detaches the current thread from a Java VM. All Java monitors held
3866    by this thread are released. All Java threads waiting for this
3867    thread to die are notified.
3868
3869    In JDK 1.1, the main thread cannot be detached from the VM. It must
3870    call DestroyJavaVM to unload the entire VM.
3871
3872    In the JDK, the main thread can be detached from the VM.
3873
3874    The main thread, which is the thread that created the Java VM,
3875    cannot be detached from the VM. Instead, the main thread must call
3876    JNI_DestroyJavaVM() to unload the entire VM.
3877
3878 *******************************************************************************/
3879
3880 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3881 {
3882 #if defined(ENABLE_THREADS)
3883         threadobject *thread;
3884
3885         STATISTICS(jniinvokation());
3886
3887         thread = threads_get_current_threadobject();
3888
3889         if (thread == NULL)
3890                 return JNI_ERR;
3891
3892         if (!localref_table_destroy())
3893                 return JNI_ERR;
3894
3895         if (!threads_detach_thread(thread))
3896                 return JNI_ERR;
3897 #endif
3898
3899         return JNI_OK;
3900 }
3901
3902
3903 /* GetEnv **********************************************************************
3904
3905    If the current thread is not attached to the VM, sets *env to NULL,
3906    and returns JNI_EDETACHED. If the specified version is not
3907    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3908    sets *env to the appropriate interface, and returns JNI_OK.
3909
3910 *******************************************************************************/
3911
3912 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3913 {
3914         STATISTICS(jniinvokation());
3915
3916 #if defined(ENABLE_THREADS)
3917         if (threads_get_current_threadobject() == NULL) {
3918                 *env = NULL;
3919
3920                 return JNI_EDETACHED;
3921         }
3922 #endif
3923
3924         /* check the JNI version */
3925
3926         switch (version) {
3927         case JNI_VERSION_1_1:
3928         case JNI_VERSION_1_2:
3929         case JNI_VERSION_1_4:
3930                 *env = _Jv_env;
3931                 return JNI_OK;
3932
3933         default:
3934                 ;
3935         }
3936
3937 #if defined(ENABLE_JVMTI)
3938         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
3939                 == JVMTI_VERSION_INTERFACE_JVMTI) {
3940
3941                 *env = (void *) jvmti_new_environment();
3942
3943                 if (env != NULL)
3944                         return JNI_OK;
3945         }
3946 #endif
3947         
3948         *env = NULL;
3949
3950         return JNI_EVERSION;
3951 }
3952
3953
3954 /* AttachCurrentThreadAsDaemon *************************************************
3955
3956    Same semantics as AttachCurrentThread, but the newly-created
3957    java.lang.Thread instance is a daemon.
3958
3959    If the thread has already been attached via either
3960    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3961    simply sets the value pointed to by penv to the JNIEnv of the
3962    current thread. In this case neither AttachCurrentThread nor this
3963    routine have any effect on the daemon status of the thread.
3964
3965 *******************************************************************************/
3966
3967 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3968 {
3969         STATISTICS(jniinvokation());
3970
3971         return jni_attach_current_thread(penv, args, true);
3972 }
3973
3974
3975 /* JNI invocation table *******************************************************/
3976
3977 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3978         NULL,
3979         NULL,
3980         NULL,
3981
3982         _Jv_JNI_DestroyJavaVM,
3983         _Jv_JNI_AttachCurrentThread,
3984         _Jv_JNI_DetachCurrentThread,
3985         _Jv_JNI_GetEnv,
3986         _Jv_JNI_AttachCurrentThreadAsDaemon
3987 };
3988
3989
3990 /* JNI function table *********************************************************/
3991
3992 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3993         NULL,
3994         NULL,
3995         NULL,
3996         NULL,    
3997         _Jv_JNI_GetVersion,
3998
3999         _Jv_JNI_DefineClass,
4000         _Jv_JNI_FindClass,
4001         _Jv_JNI_FromReflectedMethod,
4002         _Jv_JNI_FromReflectedField,
4003         _Jv_JNI_ToReflectedMethod,
4004         _Jv_JNI_GetSuperclass,
4005         _Jv_JNI_IsAssignableFrom,
4006         _Jv_JNI_ToReflectedField,
4007
4008         _Jv_JNI_Throw,
4009         _Jv_JNI_ThrowNew,
4010         _Jv_JNI_ExceptionOccurred,
4011         _Jv_JNI_ExceptionDescribe,
4012         _Jv_JNI_ExceptionClear,
4013         _Jv_JNI_FatalError,
4014         _Jv_JNI_PushLocalFrame,
4015         _Jv_JNI_PopLocalFrame,
4016
4017         _Jv_JNI_NewGlobalRef,
4018         _Jv_JNI_DeleteGlobalRef,
4019         _Jv_JNI_DeleteLocalRef,
4020         _Jv_JNI_IsSameObject,
4021         _Jv_JNI_NewLocalRef,
4022         _Jv_JNI_EnsureLocalCapacity,
4023
4024         _Jv_JNI_AllocObject,
4025         _Jv_JNI_NewObject,
4026         _Jv_JNI_NewObjectV,
4027         _Jv_JNI_NewObjectA,
4028
4029         _Jv_JNI_GetObjectClass,
4030         _Jv_JNI_IsInstanceOf,
4031
4032         _Jv_JNI_GetMethodID,
4033
4034         _Jv_JNI_CallObjectMethod,
4035         _Jv_JNI_CallObjectMethodV,
4036         _Jv_JNI_CallObjectMethodA,
4037         _Jv_JNI_CallBooleanMethod,
4038         _Jv_JNI_CallBooleanMethodV,
4039         _Jv_JNI_CallBooleanMethodA,
4040         _Jv_JNI_CallByteMethod,
4041         _Jv_JNI_CallByteMethodV,
4042         _Jv_JNI_CallByteMethodA,
4043         _Jv_JNI_CallCharMethod,
4044         _Jv_JNI_CallCharMethodV,
4045         _Jv_JNI_CallCharMethodA,
4046         _Jv_JNI_CallShortMethod,
4047         _Jv_JNI_CallShortMethodV,
4048         _Jv_JNI_CallShortMethodA,
4049         _Jv_JNI_CallIntMethod,
4050         _Jv_JNI_CallIntMethodV,
4051         _Jv_JNI_CallIntMethodA,
4052         _Jv_JNI_CallLongMethod,
4053         _Jv_JNI_CallLongMethodV,
4054         _Jv_JNI_CallLongMethodA,
4055         _Jv_JNI_CallFloatMethod,
4056         _Jv_JNI_CallFloatMethodV,
4057         _Jv_JNI_CallFloatMethodA,
4058         _Jv_JNI_CallDoubleMethod,
4059         _Jv_JNI_CallDoubleMethodV,
4060         _Jv_JNI_CallDoubleMethodA,
4061         _Jv_JNI_CallVoidMethod,
4062         _Jv_JNI_CallVoidMethodV,
4063         _Jv_JNI_CallVoidMethodA,
4064
4065         _Jv_JNI_CallNonvirtualObjectMethod,
4066         _Jv_JNI_CallNonvirtualObjectMethodV,
4067         _Jv_JNI_CallNonvirtualObjectMethodA,
4068         _Jv_JNI_CallNonvirtualBooleanMethod,
4069         _Jv_JNI_CallNonvirtualBooleanMethodV,
4070         _Jv_JNI_CallNonvirtualBooleanMethodA,
4071         _Jv_JNI_CallNonvirtualByteMethod,
4072         _Jv_JNI_CallNonvirtualByteMethodV,
4073         _Jv_JNI_CallNonvirtualByteMethodA,
4074         _Jv_JNI_CallNonvirtualCharMethod,
4075         _Jv_JNI_CallNonvirtualCharMethodV,
4076         _Jv_JNI_CallNonvirtualCharMethodA,
4077         _Jv_JNI_CallNonvirtualShortMethod,
4078         _Jv_JNI_CallNonvirtualShortMethodV,
4079         _Jv_JNI_CallNonvirtualShortMethodA,
4080         _Jv_JNI_CallNonvirtualIntMethod,
4081         _Jv_JNI_CallNonvirtualIntMethodV,
4082         _Jv_JNI_CallNonvirtualIntMethodA,
4083         _Jv_JNI_CallNonvirtualLongMethod,
4084         _Jv_JNI_CallNonvirtualLongMethodV,
4085         _Jv_JNI_CallNonvirtualLongMethodA,
4086         _Jv_JNI_CallNonvirtualFloatMethod,
4087         _Jv_JNI_CallNonvirtualFloatMethodV,
4088         _Jv_JNI_CallNonvirtualFloatMethodA,
4089         _Jv_JNI_CallNonvirtualDoubleMethod,
4090         _Jv_JNI_CallNonvirtualDoubleMethodV,
4091         _Jv_JNI_CallNonvirtualDoubleMethodA,
4092         _Jv_JNI_CallNonvirtualVoidMethod,
4093         _Jv_JNI_CallNonvirtualVoidMethodV,
4094         _Jv_JNI_CallNonvirtualVoidMethodA,
4095
4096         _Jv_JNI_GetFieldID,
4097
4098         _Jv_JNI_GetObjectField,
4099         _Jv_JNI_GetBooleanField,
4100         _Jv_JNI_GetByteField,
4101         _Jv_JNI_GetCharField,
4102         _Jv_JNI_GetShortField,
4103         _Jv_JNI_GetIntField,
4104         _Jv_JNI_GetLongField,
4105         _Jv_JNI_GetFloatField,
4106         _Jv_JNI_GetDoubleField,
4107         _Jv_JNI_SetObjectField,
4108         _Jv_JNI_SetBooleanField,
4109         _Jv_JNI_SetByteField,
4110         _Jv_JNI_SetCharField,
4111         _Jv_JNI_SetShortField,
4112         _Jv_JNI_SetIntField,
4113         _Jv_JNI_SetLongField,
4114         _Jv_JNI_SetFloatField,
4115         _Jv_JNI_SetDoubleField,
4116
4117         _Jv_JNI_GetStaticMethodID,
4118
4119         _Jv_JNI_CallStaticObjectMethod,
4120         _Jv_JNI_CallStaticObjectMethodV,
4121         _Jv_JNI_CallStaticObjectMethodA,
4122         _Jv_JNI_CallStaticBooleanMethod,
4123         _Jv_JNI_CallStaticBooleanMethodV,
4124         _Jv_JNI_CallStaticBooleanMethodA,
4125         _Jv_JNI_CallStaticByteMethod,
4126         _Jv_JNI_CallStaticByteMethodV,
4127         _Jv_JNI_CallStaticByteMethodA,
4128         _Jv_JNI_CallStaticCharMethod,
4129         _Jv_JNI_CallStaticCharMethodV,
4130         _Jv_JNI_CallStaticCharMethodA,
4131         _Jv_JNI_CallStaticShortMethod,
4132         _Jv_JNI_CallStaticShortMethodV,
4133         _Jv_JNI_CallStaticShortMethodA,
4134         _Jv_JNI_CallStaticIntMethod,
4135         _Jv_JNI_CallStaticIntMethodV,
4136         _Jv_JNI_CallStaticIntMethodA,
4137         _Jv_JNI_CallStaticLongMethod,
4138         _Jv_JNI_CallStaticLongMethodV,
4139         _Jv_JNI_CallStaticLongMethodA,
4140         _Jv_JNI_CallStaticFloatMethod,
4141         _Jv_JNI_CallStaticFloatMethodV,
4142         _Jv_JNI_CallStaticFloatMethodA,
4143         _Jv_JNI_CallStaticDoubleMethod,
4144         _Jv_JNI_CallStaticDoubleMethodV,
4145         _Jv_JNI_CallStaticDoubleMethodA,
4146         _Jv_JNI_CallStaticVoidMethod,
4147         _Jv_JNI_CallStaticVoidMethodV,
4148         _Jv_JNI_CallStaticVoidMethodA,
4149
4150         _Jv_JNI_GetStaticFieldID,
4151
4152         _Jv_JNI_GetStaticObjectField,
4153         _Jv_JNI_GetStaticBooleanField,
4154         _Jv_JNI_GetStaticByteField,
4155         _Jv_JNI_GetStaticCharField,
4156         _Jv_JNI_GetStaticShortField,
4157         _Jv_JNI_GetStaticIntField,
4158         _Jv_JNI_GetStaticLongField,
4159         _Jv_JNI_GetStaticFloatField,
4160         _Jv_JNI_GetStaticDoubleField,
4161         _Jv_JNI_SetStaticObjectField,
4162         _Jv_JNI_SetStaticBooleanField,
4163         _Jv_JNI_SetStaticByteField,
4164         _Jv_JNI_SetStaticCharField,
4165         _Jv_JNI_SetStaticShortField,
4166         _Jv_JNI_SetStaticIntField,
4167         _Jv_JNI_SetStaticLongField,
4168         _Jv_JNI_SetStaticFloatField,
4169         _Jv_JNI_SetStaticDoubleField,
4170
4171         _Jv_JNI_NewString,
4172         _Jv_JNI_GetStringLength,
4173         _Jv_JNI_GetStringChars,
4174         _Jv_JNI_ReleaseStringChars,
4175
4176         _Jv_JNI_NewStringUTF,
4177         _Jv_JNI_GetStringUTFLength,
4178         _Jv_JNI_GetStringUTFChars,
4179         _Jv_JNI_ReleaseStringUTFChars,
4180
4181         _Jv_JNI_GetArrayLength,
4182
4183         _Jv_JNI_NewObjectArray,
4184         _Jv_JNI_GetObjectArrayElement,
4185         _Jv_JNI_SetObjectArrayElement,
4186
4187         _Jv_JNI_NewBooleanArray,
4188         _Jv_JNI_NewByteArray,
4189         _Jv_JNI_NewCharArray,
4190         _Jv_JNI_NewShortArray,
4191         _Jv_JNI_NewIntArray,
4192         _Jv_JNI_NewLongArray,
4193         _Jv_JNI_NewFloatArray,
4194         _Jv_JNI_NewDoubleArray,
4195
4196         _Jv_JNI_GetBooleanArrayElements,
4197         _Jv_JNI_GetByteArrayElements,
4198         _Jv_JNI_GetCharArrayElements,
4199         _Jv_JNI_GetShortArrayElements,
4200         _Jv_JNI_GetIntArrayElements,
4201         _Jv_JNI_GetLongArrayElements,
4202         _Jv_JNI_GetFloatArrayElements,
4203         _Jv_JNI_GetDoubleArrayElements,
4204
4205         _Jv_JNI_ReleaseBooleanArrayElements,
4206         _Jv_JNI_ReleaseByteArrayElements,
4207         _Jv_JNI_ReleaseCharArrayElements,
4208         _Jv_JNI_ReleaseShortArrayElements,
4209         _Jv_JNI_ReleaseIntArrayElements,
4210         _Jv_JNI_ReleaseLongArrayElements,
4211         _Jv_JNI_ReleaseFloatArrayElements,
4212         _Jv_JNI_ReleaseDoubleArrayElements,
4213
4214         _Jv_JNI_GetBooleanArrayRegion,
4215         _Jv_JNI_GetByteArrayRegion,
4216         _Jv_JNI_GetCharArrayRegion,
4217         _Jv_JNI_GetShortArrayRegion,
4218         _Jv_JNI_GetIntArrayRegion,
4219         _Jv_JNI_GetLongArrayRegion,
4220         _Jv_JNI_GetFloatArrayRegion,
4221         _Jv_JNI_GetDoubleArrayRegion,
4222         _Jv_JNI_SetBooleanArrayRegion,
4223         _Jv_JNI_SetByteArrayRegion,
4224         _Jv_JNI_SetCharArrayRegion,
4225         _Jv_JNI_SetShortArrayRegion,
4226         _Jv_JNI_SetIntArrayRegion,
4227         _Jv_JNI_SetLongArrayRegion,
4228         _Jv_JNI_SetFloatArrayRegion,
4229         _Jv_JNI_SetDoubleArrayRegion,
4230
4231         _Jv_JNI_RegisterNatives,
4232         _Jv_JNI_UnregisterNatives,
4233
4234         _Jv_JNI_MonitorEnter,
4235         _Jv_JNI_MonitorExit,
4236
4237         _Jv_JNI_GetJavaVM,
4238
4239         /* New JNI 1.2 functions. */
4240
4241         _Jv_JNI_GetStringRegion,
4242         _Jv_JNI_GetStringUTFRegion,
4243
4244         _Jv_JNI_GetPrimitiveArrayCritical,
4245         _Jv_JNI_ReleasePrimitiveArrayCritical,
4246
4247         _Jv_JNI_GetStringCritical,
4248         _Jv_JNI_ReleaseStringCritical,
4249
4250         _Jv_JNI_NewWeakGlobalRef,
4251         _Jv_JNI_DeleteWeakGlobalRef,
4252
4253         _Jv_JNI_ExceptionCheck,
4254
4255         /* New JNI 1.4 functions. */
4256
4257         _Jv_JNI_NewDirectByteBuffer,
4258         _Jv_JNI_GetDirectBufferAddress,
4259         _Jv_JNI_GetDirectBufferCapacity,
4260
4261         /* New JNI 1.6 functions. */
4262
4263         jni_GetObjectRefType
4264 };
4265
4266
4267 /* Invocation API Functions ***************************************************/
4268
4269 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4270
4271    Returns a default configuration for the Java VM.
4272
4273 *******************************************************************************/
4274
4275 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4276 {
4277         JavaVMInitArgs *_vm_args;
4278
4279         _vm_args = (JavaVMInitArgs *) vm_args;
4280
4281         /* GNU classpath currently supports JNI 1.2 */
4282
4283         switch (_vm_args->version) {
4284     case JNI_VERSION_1_1:
4285                 _vm_args->version = JNI_VERSION_1_1;
4286                 break;
4287
4288     case JNI_VERSION_1_2:
4289     case JNI_VERSION_1_4:
4290                 _vm_args->ignoreUnrecognized = JNI_FALSE;
4291                 _vm_args->options = NULL;
4292                 _vm_args->nOptions = 0;
4293                 break;
4294
4295     default:
4296                 return -1;
4297         }
4298   
4299         return 0;
4300 }
4301
4302
4303 /* JNI_GetCreatedJavaVMs *******************************************************
4304
4305    Returns all Java VMs that have been created. Pointers to VMs are written in
4306    the buffer vmBuf in the order they are created. At most bufLen number of
4307    entries will be written. The total number of created VMs is returned in
4308    *nVMs.
4309
4310 *******************************************************************************/
4311
4312 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4313 {
4314         TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
4315
4316         if (bufLen <= 0)
4317                 return JNI_ERR;
4318
4319         /* We currently only support 1 VM running. */
4320
4321         vmBuf[0] = (JavaVM *) _Jv_jvm;
4322         *nVMs    = 1;
4323
4324     return JNI_OK;
4325 }
4326
4327
4328 /* JNI_CreateJavaVM ************************************************************
4329
4330    Loads and initializes a Java VM. The current thread becomes the main thread.
4331    Sets the env argument to the JNI interface pointer of the main thread.
4332
4333 *******************************************************************************/
4334
4335 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4336 {
4337         TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
4338
4339         /* actually create the JVM */
4340
4341         if (!vm_createjvm(p_vm, p_env, vm_args))
4342                 return JNI_ERR;
4343
4344         return JNI_OK;
4345 }
4346
4347
4348 /*
4349  * These are local overrides for various environment variables in Emacs.
4350  * Please do not remove this and leave it at the end of the file, where
4351  * Emacs will automagically detect them.
4352  * ---------------------------------------------------------------------
4353  * Local variables:
4354  * mode: c
4355  * indent-tabs-mode: t
4356  * c-basic-offset: 4
4357  * tab-width: 4
4358  * End:
4359  * vim:noexpandtab:sw=4:ts=4:
4360  */