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