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