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