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