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