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