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