* src/vm/vm.c (_Jv_jvm): Changed type to _Jv_JavaVM.
[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 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    Contact: cacao@cacaojvm.org
26
27    Authors: Rainhard Grafl
28             Roman Obermaisser
29
30    Changes: Joseph Wenninger
31             Martin Platter
32             Christian Thalinger
33                         Edwin Steiner
34
35    $Id: jni.c 4565 2006-03-07 09:40:37Z twisti $
36
37 */
38
39
40 #include "config.h"
41
42 #include <assert.h>
43 #include <string.h>
44
45 #include "vm/types.h"
46
47 #include "mm/boehm.h"
48 #include "mm/memory.h"
49 #include "native/jni.h"
50 #include "native/native.h"
51
52 #include "native/include/gnu_classpath_Pointer.h"
53
54 #if SIZEOF_VOID_P == 8
55 # include "native/include/gnu_classpath_Pointer64.h"
56 #else
57 # include "native/include/gnu_classpath_Pointer32.h"
58 #endif
59
60 #include "native/include/java_lang_Object.h"
61 #include "native/include/java_lang_Byte.h"
62 #include "native/include/java_lang_Character.h"
63 #include "native/include/java_lang_Short.h"
64 #include "native/include/java_lang_Integer.h"
65 #include "native/include/java_lang_Boolean.h"
66 #include "native/include/java_lang_Long.h"
67 #include "native/include/java_lang_Float.h"
68 #include "native/include/java_lang_Double.h"
69 #include "native/include/java_lang_Throwable.h"
70 #include "native/include/java_lang_reflect_Method.h"
71 #include "native/include/java_lang_reflect_Constructor.h"
72 #include "native/include/java_lang_reflect_Field.h"
73
74 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
75 #include "native/include/java_lang_VMClass.h"
76 #include "native/include/java_lang_VMClassLoader.h"
77 #include "native/include/java_nio_Buffer.h"
78 #include "native/include/java_nio_DirectByteBufferImpl.h"
79
80 #if defined(ENABLE_JVMTI)
81 # include "native/jvmti/jvmti.h"
82 #endif
83
84 #if defined(USE_THREADS)
85 # if defined(NATIVE_THREADS)
86 #  include "threads/native/threads.h"
87 # else
88 #  include "threads/green/threads.h"
89 # endif
90 #endif
91
92 #include "toolbox/logging.h"
93 #include "vm/builtin.h"
94 #include "vm/exceptions.h"
95 #include "vm/global.h"
96 #include "vm/initialize.h"
97 #include "vm/loader.h"
98 #include "vm/options.h"
99 #include "vm/resolve.h"
100 #include "vm/statistics.h"
101 #include "vm/stringlocal.h"
102 #include "vm/jit/asmpart.h"
103 #include "vm/jit/jit.h"
104 #include "vm/statistics.h"
105 #include "vm/vm.h"
106
107
108 /* global variables ***********************************************************/
109
110 /* global reference table *****************************************************/
111
112 static java_objectheader **global_ref_table;
113
114 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
115 static classinfo *ihmclass = NULL;
116 static methodinfo *putmid = NULL;
117 static methodinfo *getmid = NULL;
118 static methodinfo *removemid = NULL;
119
120
121 /* direct buffer stuff ********************************************************/
122
123 static classinfo *class_java_nio_Buffer;
124 static classinfo *class_java_nio_DirectByteBufferImpl;
125 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
126 #if SIZEOF_VOID_P == 8
127 static classinfo *class_gnu_classpath_Pointer64;
128 #else
129 static classinfo *class_gnu_classpath_Pointer32;
130 #endif
131
132 static methodinfo *dbbirw_init;
133
134
135 /* local reference table ******************************************************/
136
137 #if !defined(USE_THREADS)
138 localref_table *_no_threads_localref_table;
139 #endif
140
141
142 /* accessing instance fields macros *******************************************/
143
144 #define SET_FIELD(o,type,f,value) \
145     *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
146
147 #define GET_FIELD(o,type,f) \
148     *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
149
150
151 /* some forward declarations **************************************************/
152
153 jobject NewLocalRef(JNIEnv *env, jobject ref);
154
155
156 /* jni_init ********************************************************************
157
158    Initialize the JNI subsystem.
159
160 *******************************************************************************/
161
162 bool jni_init(void)
163 {
164         /* initalize global reference table */
165
166         if (!(ihmclass =
167                   load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
168                 return false;
169
170         global_ref_table = GCNEW(jobject);
171
172         if (!(*global_ref_table = native_new_and_init(ihmclass)))
173                 return false;
174
175         if (!(getmid = class_resolvemethod(ihmclass, utf_get,
176                                                                            utf_java_lang_Object__java_lang_Object)))
177                 return false;
178
179         if (!(putmid = class_resolvemethod(ihmclass, utf_put,
180                                                                            utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
181                 return false;
182
183         if (!(removemid =
184                   class_resolvemethod(ihmclass, utf_remove,
185                                                           utf_java_lang_Object__java_lang_Object)))
186                 return false;
187
188
189         /* direct buffer stuff */
190
191         if (!(class_java_nio_Buffer =
192                   load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
193                 !link_class(class_java_nio_Buffer))
194                 return false;
195
196         if (!(class_java_nio_DirectByteBufferImpl =
197                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
198                 !link_class(class_java_nio_DirectByteBufferImpl))
199                 return false;
200
201         if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
202                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
203                 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
204                 return false;
205
206         if (!(dbbirw_init =
207                 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
208                                                         utf_init,
209                                                         utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
210                 return false;
211
212 #if SIZEOF_VOID_P == 8
213         if (!(class_gnu_classpath_Pointer64 =
214                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
215                 !link_class(class_gnu_classpath_Pointer64))
216                 return false;
217 #else
218         if (!(class_gnu_classpath_Pointer32 =
219                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
220                 !link_class(class_gnu_classpath_Pointer32))
221                 return false;
222 #endif
223
224         return true;
225 }
226
227
228 /* _Jv_jni_vmargs_from_objectarray *********************************************
229
230    XXX
231
232 *******************************************************************************/
233
234 static bool _Jv_jni_vmargs_from_objectarray(java_objectheader *o,
235                                                                                         methoddesc *descr,
236                                                                                         vm_arg *vmargs,
237                                                                                         java_objectarray *params)
238 {
239         java_objectheader *param;
240         s4                 paramcount;
241         typedesc          *paramtypes;
242         classinfo         *c;
243         s4                 i;
244         s4                 j;
245
246         paramcount = descr->paramcount;
247         paramtypes = descr->paramtypes;
248
249         /* if method is non-static fill first block and skip `this' pointer */
250
251         i = 0;
252
253         if (o != NULL) {
254                 /* this pointer */
255                 vmargs[0].type = TYPE_ADR;
256                 vmargs[0].data = (u8) (ptrint) o;
257
258                 paramtypes++;
259                 paramcount--;
260                 i++;
261         }
262
263         for (j = 0; j < paramcount; i++, j++, paramtypes++) {
264                 switch (paramtypes->type) {
265                 /* primitive types */
266                 case TYPE_INT:
267                 case TYPE_LONG:
268                 case TYPE_FLOAT:
269                 case TYPE_DOUBLE:
270                         param = params->data[j];
271
272                         if (param == NULL)
273                                 goto illegal_arg;
274
275                         /* internally used data type */
276                         vmargs[i].type = paramtypes->type;
277
278                         /* convert the value according to its declared type */
279
280                         c = param->vftbl->class;
281
282                         switch (paramtypes->decltype) {
283                         case PRIMITIVETYPE_BOOLEAN:
284                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
285                                         vmargs[i].data = (s8) ((java_lang_Boolean *) param)->value;
286                                 else
287                                         goto illegal_arg;
288                                 break;
289
290                         case PRIMITIVETYPE_BYTE:
291                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
292                                         vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
293                                 else
294                                         goto illegal_arg;
295                                 break;
296
297                         case PRIMITIVETYPE_CHAR:
298                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
299                                         vmargs[i].data = (s8) ((java_lang_Character *) param)->value;
300                                 else
301                                         goto illegal_arg;
302                                 break;
303
304                         case PRIMITIVETYPE_SHORT:
305                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
306                                         vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
307                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
308                                         vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
309                                 else
310                                         goto illegal_arg;
311                                 break;
312
313                         case PRIMITIVETYPE_INT:
314                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
315                                         vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
316                                 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
317                                         vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
318                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
319                                         vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
320                                 else
321                                         goto illegal_arg;
322                                 break;
323
324                         case PRIMITIVETYPE_LONG:
325                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
326                                         vmargs[i].data = (s8) ((java_lang_Long *) param)->value;
327                                 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
328                                         vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
329                                 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
330                                         vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
331                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
332                                         vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
333                                 else
334                                         goto illegal_arg;
335                                 break;
336
337                         case PRIMITIVETYPE_FLOAT:
338                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
339                                         *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
340                                 else
341                                         goto illegal_arg;
342                                 break;
343
344                         case PRIMITIVETYPE_DOUBLE:
345                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
346                                         *((jdouble *) (&vmargs[i].data)) = (jdouble) ((java_lang_Double *) param)->value;
347                                 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
348                                         *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
349                                 else
350                                         goto illegal_arg;
351                                 break;
352
353                         default:
354                                 goto illegal_arg;
355                         }
356                         break;
357                 
358                         case TYPE_ADDRESS:
359                                 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
360                                         return false;
361
362                                 if (params->data[j] != 0) {
363                                         if (paramtypes->arraydim > 0) {
364                                                 if (!builtin_arrayinstanceof(params->data[j], c))
365                                                         goto illegal_arg;
366
367                                         } else {
368                                                 if (!builtin_instanceof(params->data[j], c))
369                                                         goto illegal_arg;
370                                         }
371                                 }
372                                 vmargs[i].type = TYPE_ADR;
373                                 vmargs[i].data = (u8) (ptrint) params->data[j];
374                                 break;
375
376                         default:
377                                 goto illegal_arg;
378                 }
379         }
380
381 /*      if (rettype) */
382 /*              *rettype = descr->returntype.decltype; */
383
384         return true;
385
386 illegal_arg:
387         exceptions_throw_illegalargumentexception();
388         return false;
389 }
390
391
392 /* _Jv_jni_CallObjectMethod ****************************************************
393
394    Internal function to call Java Object methods.
395
396 *******************************************************************************/
397
398 static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
399                                                                                                    vftbl_t *vftbl,
400                                                                                                    methodinfo *m, va_list ap)
401 {
402         methodinfo        *resm;
403         java_objectheader *ro;
404
405         STATISTICS(jniinvokation());
406
407         if (m == NULL) {
408                 exceptions_throw_nullpointerexception();
409                 return NULL;
410         }
411
412         /* Class initialization is done by the JIT compiler.  This is ok
413            since a static method always belongs to the declaring class. */
414
415         if (m->flags & ACC_STATIC) {
416                 /* For static methods we reset the object. */
417
418                 if (o != NULL)
419                         o = NULL;
420
421                 /* for convenience */
422
423                 resm = m;
424
425         } else {
426                 /* For instance methods we make a virtual function table lookup. */
427
428                 resm = method_vftbl_lookup(vftbl, m);
429         }
430
431         STATISTICS(jnicallXmethodnvokation());
432
433         ro = vm_call_method_valist(resm, o, ap);
434
435         return ro;
436 }
437
438
439 /* _Jv_jni_CallObjectMethodA ***************************************************
440
441    Internal function to call Java Object methods.
442
443 *******************************************************************************/
444
445 static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
446                                                                                                         vftbl_t *vftbl,
447                                                                                                         methodinfo *m, jvalue *args)
448 {
449         methodinfo        *resm;
450         java_objectheader *ro;
451
452         STATISTICS(jniinvokation());
453
454         if (m == NULL) {
455                 exceptions_throw_nullpointerexception();
456                 return NULL;
457         }
458
459         /* Class initialization is done by the JIT compiler.  This is ok
460            since a static method always belongs to the declaring class. */
461
462         if (m->flags & ACC_STATIC) {
463                 /* For static methods we reset the object. */
464
465                 if (o != NULL)
466                         o = NULL;
467
468                 /* for convenience */
469
470                 resm = m;
471
472         } else {
473                 /* For instance methods we make a virtual function table lookup. */
474
475                 resm = method_vftbl_lookup(vftbl, m);
476         }
477
478         STATISTICS(jnicallXmethodnvokation());
479
480         ro = vm_call_method_jvalue(resm, o, args);
481
482         return ro;
483 }
484
485
486 /* _Jv_jni_CallIntMethod *******************************************************
487
488    Internal function to call Java integer class methods (boolean,
489    byte, char, short, int).
490
491 *******************************************************************************/
492
493 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
494                                                                   methodinfo *m, va_list ap)
495 {
496         methodinfo *resm;
497         jint        i;
498
499         STATISTICS(jniinvokation());
500
501         if (m == NULL) {
502                 exceptions_throw_nullpointerexception();
503                 return 0;
504         }
505         
506         /* Class initialization is done by the JIT compiler.  This is ok
507            since a static method always belongs to the declaring class. */
508
509         if (m->flags & ACC_STATIC) {
510                 /* For static methods we reset the object. */
511
512                 if (o != NULL)
513                         o = NULL;
514
515                 /* for convenience */
516
517                 resm = m;
518
519         } else {
520                 /* For instance methods we make a virtual function table lookup. */
521
522                 resm = method_vftbl_lookup(vftbl, m);
523         }
524
525         STATISTICS(jnicallXmethodnvokation());
526
527         i = vm_call_method_int_valist(resm, o, ap);
528
529         return i;
530 }
531
532
533 /* _Jv_jni_CallLongMethod ******************************************************
534
535    Internal function to call Java long methods.
536
537 *******************************************************************************/
538
539 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
540                                                                         methodinfo *m, va_list ap)
541 {
542         methodinfo *resm;
543         jlong       l;
544
545         STATISTICS(jniinvokation());
546
547         if (m == NULL) {
548                 exceptions_throw_nullpointerexception();
549                 return 0;
550         }
551
552         /* Class initialization is done by the JIT compiler.  This is ok
553            since a static method always belongs to the declaring class. */
554
555         if (m->flags & ACC_STATIC) {
556                 /* For static methods we reset the object. */
557
558                 if (o != NULL)
559                         o = NULL;
560
561                 /* for convenience */
562
563                 resm = m;
564
565         } else {
566                 /* For instance methods we make a virtual function table lookup. */
567
568                 resm = method_vftbl_lookup(vftbl, m);
569         }
570
571         STATISTICS(jnicallXmethodnvokation());
572
573         l = vm_call_method_long_valist(resm, o, ap);
574
575         return l;
576 }
577
578
579 /* _Jv_jni_CallFloatMethod *****************************************************
580
581    Internal function to call Java float methods.
582
583 *******************************************************************************/
584
585 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
586                                                                           methodinfo *m, va_list ap)
587 {
588         methodinfo *resm;
589         jfloat      f;
590
591         /* Class initialization is done by the JIT compiler.  This is ok
592            since a static method always belongs to the declaring class. */
593
594         if (m->flags & ACC_STATIC) {
595                 /* For static methods we reset the object. */
596
597                 if (o != NULL)
598                         o = NULL;
599
600                 /* for convenience */
601
602                 resm = m;
603
604         } else {
605                 /* For instance methods we make a virtual function table lookup. */
606
607                 resm = method_vftbl_lookup(vftbl, m);
608         }
609
610         STATISTICS(jnicallXmethodnvokation());
611
612         f = vm_call_method_float_valist(resm, o, ap);
613
614         return f;
615 }
616
617
618 /* _Jv_jni_CallDoubleMethod ****************************************************
619
620    Internal function to call Java double methods.
621
622 *******************************************************************************/
623
624 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
625                                                                                 methodinfo *m, va_list ap)
626 {
627         methodinfo *resm;
628         jdouble     d;
629
630         /* Class initialization is done by the JIT compiler.  This is ok
631            since a static method always belongs to the declaring class. */
632
633         if (m->flags & ACC_STATIC) {
634                 /* For static methods we reset the object. */
635
636                 if (o != NULL)
637                         o = NULL;
638
639                 /* for convenience */
640
641                 resm = m;
642
643         } else {
644                 /* For instance methods we make a virtual function table lookup. */
645
646                 resm = method_vftbl_lookup(vftbl, m);
647         }
648
649         d = vm_call_method_double_valist(resm, o, ap);
650
651         return d;
652 }
653
654
655 /* _Jv_jni_CallVoidMethod ******************************************************
656
657    Internal function to call Java void methods.
658
659 *******************************************************************************/
660
661 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
662                                                                    methodinfo *m, va_list ap)
663 {       
664         methodinfo *resm;
665
666         if (m == NULL) {
667                 exceptions_throw_nullpointerexception();
668                 return;
669         }
670
671         /* Class initialization is done by the JIT compiler.  This is ok
672            since a static method always belongs to the declaring class. */
673
674         if (m->flags & ACC_STATIC) {
675                 /* For static methods we reset the object. */
676
677                 if (o != NULL)
678                         o = NULL;
679
680                 /* for convenience */
681
682                 resm = m;
683
684         } else {
685                 /* For instance methods we make a virtual function table lookup. */
686
687                 resm = method_vftbl_lookup(vftbl, m);
688         }
689
690         STATISTICS(jnicallXmethodnvokation());
691
692         (void) vm_call_method_valist(resm, o, ap);
693 }
694
695
696 /* _Jv_jni_CallVoidMethodA *****************************************************
697
698    Internal function to call Java void methods.
699
700 *******************************************************************************/
701
702 static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
703                                                                         methodinfo *m, jvalue *args)
704 {       
705         methodinfo *resm;
706
707         if (m == NULL) {
708                 exceptions_throw_nullpointerexception();
709                 return;
710         }
711
712         /* Class initialization is done by the JIT compiler.  This is ok
713            since a static method always belongs to the declaring class. */
714
715         if (m->flags & ACC_STATIC) {
716                 /* For static methods we reset the object. */
717
718                 if (o != NULL)
719                         o = NULL;
720
721                 /* for convenience */
722
723                 resm = m;
724
725         } else {
726                 /* For instance methods we make a virtual function table lookup. */
727
728                 resm = method_vftbl_lookup(vftbl, m);
729         }
730
731         STATISTICS(jnicallXmethodnvokation());
732
733         (void) vm_call_method_jvalue(resm, o, args);
734 }
735
736
737 /* _Jv_jni_invokeNative ********************************************************
738
739    Invoke a method on the given object with the given arguments.
740
741    For instance methods OBJ must be != NULL and the method is looked up
742    in the vftbl of the object.
743
744    For static methods, OBJ is ignored.
745
746 *******************************************************************************/
747
748 java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
749                                                                                 java_objectarray *params)
750 {
751         methodinfo        *resm;
752         vm_arg            *vmargs;
753         java_objectheader *ro;
754         s4                 argcount;
755         s4                 paramcount;
756
757         if (!m) {
758                 exceptions_throw_nullpointerexception();
759                 return NULL;
760         }
761
762         argcount = m->parseddesc->paramcount;
763         paramcount = argcount;
764
765         /* if method is non-static, remove the `this' pointer */
766
767         if (!(m->flags & ACC_STATIC))
768                 paramcount--;
769
770         /* For instance methods the object has to be an instance of the
771            class the method belongs to. For static methods the obj
772            parameter is ignored. */
773
774         if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
775                 *exceptionptr =
776                         new_exception_message(string_java_lang_IllegalArgumentException,
777                                                                   "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
778                 return NULL;
779         }
780
781         /* check if we got the right number of arguments */
782
783         if (((params == NULL) && (paramcount != 0)) ||
784                 (params && (params->header.size != paramcount))) 
785         {
786                 *exceptionptr =
787                         new_exception(string_java_lang_IllegalArgumentException);
788                 return NULL;
789         }
790
791         /* for instance methods we need an object */
792
793         if (!(m->flags & ACC_STATIC) && (o == NULL)) {
794                 *exceptionptr =
795                         new_exception_message(string_java_lang_NullPointerException,
796                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
797                 return NULL;
798         }
799
800         /* for static methods, zero object to make subsequent code simpler */
801         if (m->flags & ACC_STATIC)
802                 o = NULL;
803
804         if (o != NULL) {
805                 /* for instance methods we must do a vftbl lookup */
806                 resm = method_vftbl_lookup(o->vftbl, m);
807
808         } else {
809                 /* for static methods, just for convenience */
810                 resm = m;
811         }
812
813         vmargs = MNEW(vm_arg, argcount);
814
815         if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params))
816                 return NULL;
817
818         switch (resm->parseddesc->returntype.decltype) {
819         case TYPE_VOID:
820                 (void) vm_call_method_vmarg(resm, argcount, vmargs);
821
822                 ro = NULL;
823                 break;
824
825         case PRIMITIVETYPE_BOOLEAN: {
826                 s4 i;
827                 java_lang_Boolean *bo;
828
829                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
830
831                 ro = builtin_new(class_java_lang_Boolean);
832
833                 /* setting the value of the object direct */
834
835                 bo = (java_lang_Boolean *) ro;
836                 bo->value = i;
837         }
838         break;
839
840         case PRIMITIVETYPE_BYTE: {
841                 s4 i;
842                 java_lang_Byte *bo;
843
844                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
845
846                 ro = builtin_new(class_java_lang_Byte);
847
848                 /* setting the value of the object direct */
849
850                 bo = (java_lang_Byte *) ro;
851                 bo->value = i;
852         }
853         break;
854
855         case PRIMITIVETYPE_CHAR: {
856                 s4 i;
857                 java_lang_Character *co;
858
859                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
860
861                 ro = builtin_new(class_java_lang_Character);
862
863                 /* setting the value of the object direct */
864
865                 co = (java_lang_Character *) ro;
866                 co->value = i;
867         }
868         break;
869
870         case PRIMITIVETYPE_SHORT: {
871                 s4 i;
872                 java_lang_Short *so;
873
874                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
875
876                 ro = builtin_new(class_java_lang_Short);
877
878                 /* setting the value of the object direct */
879
880                 so = (java_lang_Short *) ro;
881                 so->value = i;
882         }
883         break;
884
885         case PRIMITIVETYPE_INT: {
886                 s4 i;
887                 java_lang_Integer *io;
888
889                 i = vm_call_method_int_vmarg(resm, argcount, vmargs);
890
891                 ro = builtin_new(class_java_lang_Integer);
892
893                 /* setting the value of the object direct */
894
895                 io = (java_lang_Integer *) ro;
896                 io->value = i;
897         }
898         break;
899
900         case PRIMITIVETYPE_LONG: {
901                 s8 l;
902                 java_lang_Long *lo;
903
904                 l = vm_call_method_long_vmarg(resm, argcount, vmargs);
905
906                 ro = builtin_new(class_java_lang_Long);
907
908                 /* setting the value of the object direct */
909
910                 lo = (java_lang_Long *) ro;
911                 lo->value = l;
912         }
913         break;
914
915         case PRIMITIVETYPE_FLOAT: {
916                 float f;
917                 java_lang_Float *fo;
918
919                 f = vm_call_method_float_vmarg(resm, argcount, vmargs);
920
921                 ro = builtin_new(class_java_lang_Float);
922
923                 /* setting the value of the object direct */
924
925                 fo = (java_lang_Float *) ro;
926                 fo->value = f;
927         }
928         break;
929
930         case PRIMITIVETYPE_DOUBLE: {
931                 double d;
932                 java_lang_Double *_do;
933
934                 d = vm_call_method_double_vmarg(resm, argcount, vmargs);
935
936                 ro = builtin_new(class_java_lang_Double);
937
938                 /* setting the value of the object direct */
939
940                 _do = (java_lang_Double *) ro;
941                 _do->value = d;
942         }
943         break;
944
945         case TYPE_ADR:
946                 ro = vm_call_method_vmarg(resm, argcount, vmargs);
947                 break;
948
949         default:
950                 /* if this happens the exception has already been set by
951                    fill_callblock_from_objectarray */
952
953                 MFREE(vmargs, vm_arg, argcount);
954
955                 return NULL;
956         }
957
958         MFREE(vmargs, vm_arg, argcount);
959
960         if (*exceptionptr) {
961                 java_objectheader *cause;
962
963                 cause = *exceptionptr;
964
965                 /* clear exception pointer, we are calling JIT code again */
966
967                 *exceptionptr = NULL;
968
969                 *exceptionptr =
970                         new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
971                                                                         (java_lang_Throwable *) cause);
972         }
973
974         return ro;
975 }
976
977
978 /* GetVersion ******************************************************************
979
980    Returns the major version number in the higher 16 bits and the
981    minor version number in the lower 16 bits.
982
983 *******************************************************************************/
984
985 jint GetVersion(JNIEnv *env)
986 {
987         STATISTICS(jniinvokation());
988
989         /* we support JNI 1.4 */
990
991         return JNI_VERSION_1_4;
992 }
993
994
995 /* Class Operations ***********************************************************/
996
997 /* DefineClass *****************************************************************
998
999    Loads a class from a buffer of raw class data. The buffer
1000    containing the raw class data is not referenced by the VM after the
1001    DefineClass call returns, and it may be discarded if desired.
1002
1003 *******************************************************************************/
1004
1005 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
1006                                    const jbyte *buf, jsize bufLen)
1007 {
1008         java_lang_ClassLoader *cl;
1009         java_lang_String      *s;
1010         java_bytearray        *ba;
1011         jclass                 c;
1012
1013         STATISTICS(jniinvokation());
1014
1015         cl = (java_lang_ClassLoader *) loader;
1016         s = javastring_new_char(name);
1017         ba = (java_bytearray *) buf;
1018
1019         c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
1020                                                                                                                   0, bufLen, NULL);
1021
1022         return (jclass) NewLocalRef(env, (jobject) c);
1023 }
1024
1025
1026 /* FindClass *******************************************************************
1027
1028    This function loads a locally-defined class. It searches the
1029    directories and zip files specified by the CLASSPATH environment
1030    variable for the class with the specified name.
1031
1032 *******************************************************************************/
1033
1034 jclass FindClass(JNIEnv *env, const char *name)
1035 {
1036         utf       *u;
1037         classinfo *cc;
1038         classinfo *c;
1039
1040         STATISTICS(jniinvokation());
1041
1042         u = utf_new_char_classname((char *) name);
1043
1044         /* Check stacktrace for classloader, if one found use it,
1045            otherwise use the system classloader. */
1046
1047         /* Quote from the JNI documentation:
1048          
1049            In the Java 2 Platform, FindClass locates the class loader
1050            associated with the current native method.  If the native code
1051            belongs to a system class, no class loader will be
1052            involved. Otherwise, the proper class loader will be invoked to
1053            load and link the named class. When FindClass is called through
1054            the Invocation Interface, there is no current native method or
1055            its associated class loader. In that case, the result of
1056            ClassLoader.getBaseClassLoader is used." */
1057
1058 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
1059         /* these JITs support stacktraces, and so does the interpreter */
1060
1061         cc = stacktrace_getCurrentClass();
1062 #else
1063 # if defined(ENABLE_INTRP)
1064         /* the interpreter supports stacktraces, even if the JIT does not */
1065
1066         if (opt_intrp)
1067                 cc = stacktrace_getCurrentClass();
1068         else
1069 # endif
1070                 cc = NULL;
1071 #endif
1072
1073         /* if no Java method was found, use the system classloader */
1074
1075         if (cc == NULL)
1076                 c = load_class_from_sysloader(u);
1077         else
1078                 c = load_class_from_classloader(u, cc->classloader);
1079
1080         if (c == NULL)
1081                 return NULL;
1082
1083         if (!link_class(c))
1084                 return NULL;
1085
1086         return (jclass) NewLocalRef(env, (jobject) c);
1087 }
1088   
1089
1090 /* GetSuperclass ***************************************************************
1091
1092    If clazz represents any class other than the class Object, then
1093    this function returns the object that represents the superclass of
1094    the class specified by clazz.
1095
1096 *******************************************************************************/
1097  
1098 jclass GetSuperclass(JNIEnv *env, jclass sub)
1099 {
1100         classinfo *c;
1101
1102         STATISTICS(jniinvokation());
1103
1104         c = ((classinfo *) sub)->super.cls;
1105
1106         if (!c)
1107                 return NULL;
1108
1109         return (jclass) NewLocalRef(env, (jobject) c);
1110 }
1111   
1112  
1113 /* IsAssignableFrom ************************************************************
1114
1115    Determines whether an object of sub can be safely cast to sup.
1116
1117 *******************************************************************************/
1118
1119 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1120 {
1121         STATISTICS(jniinvokation());
1122
1123         return Java_java_lang_VMClass_isAssignableFrom(env,
1124                                                                                                    NULL,
1125                                                                                                    (java_lang_Class *) sup,
1126                                                                                                    (java_lang_Class *) sub);
1127 }
1128
1129
1130 /* Throw ***********************************************************************
1131
1132    Causes a java.lang.Throwable object to be thrown.
1133
1134 *******************************************************************************/
1135
1136 jint Throw(JNIEnv *env, jthrowable obj)
1137 {
1138         STATISTICS(jniinvokation());
1139
1140         *exceptionptr = (java_objectheader *) obj;
1141
1142         return JNI_OK;
1143 }
1144
1145
1146 /* ThrowNew ********************************************************************
1147
1148    Constructs an exception object from the specified class with the
1149    message specified by message and causes that exception to be
1150    thrown.
1151
1152 *******************************************************************************/
1153
1154 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1155 {
1156         java_lang_Throwable *o;
1157         java_lang_String    *s;
1158
1159         STATISTICS(jniinvokation());
1160
1161         s = (java_lang_String *) javastring_new_char(msg);
1162
1163         /* instantiate exception object */
1164
1165         o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
1166                                                                                                                    s);
1167
1168         if (!o)
1169                 return -1;
1170
1171         *exceptionptr = (java_objectheader *) o;
1172
1173         return 0;
1174 }
1175
1176
1177 /* ExceptionOccurred ***********************************************************
1178
1179    Determines if an exception is being thrown. The exception stays
1180    being thrown until either the native code calls ExceptionClear(),
1181    or the Java code handles the exception.
1182
1183 *******************************************************************************/
1184
1185 jthrowable ExceptionOccurred(JNIEnv *env)
1186 {
1187         java_objectheader *e;
1188
1189         STATISTICS(jniinvokation());
1190
1191         e = *exceptionptr;
1192
1193         return NewLocalRef(env, (jthrowable) e);
1194 }
1195
1196
1197 /* ExceptionDescribe ***********************************************************
1198
1199    Prints an exception and a backtrace of the stack to a system
1200    error-reporting channel, such as stderr. This is a convenience
1201    routine provided for debugging.
1202
1203 *******************************************************************************/
1204
1205 void ExceptionDescribe(JNIEnv *env)
1206 {
1207         java_objectheader *e;
1208         methodinfo        *m;
1209
1210         STATISTICS(jniinvokation());
1211
1212         e = *exceptionptr;
1213
1214         if (e) {
1215                 /* clear exception, because we are calling jit code again */
1216
1217                 *exceptionptr = NULL;
1218
1219                 /* get printStackTrace method from exception class */
1220
1221                 m = class_resolveclassmethod(e->vftbl->class,
1222                                                                          utf_printStackTrace,
1223                                                                          utf_void__void,
1224                                                                          NULL,
1225                                                                          true);
1226
1227                 if (!m)
1228                         /* XXX what should we do? */
1229                         return;
1230
1231                 /* print the stacktrace */
1232
1233                 (void) vm_call_method(m, e);
1234         }
1235 }
1236
1237
1238 /* ExceptionClear **************************************************************
1239
1240    Clears any exception that is currently being thrown. If no
1241    exception is currently being thrown, this routine has no effect.
1242
1243 *******************************************************************************/
1244
1245 void ExceptionClear(JNIEnv *env)
1246 {
1247         STATISTICS(jniinvokation());
1248
1249         *exceptionptr = NULL;
1250 }
1251
1252
1253 /* FatalError ******************************************************************
1254
1255    Raises a fatal error and does not expect the VM to recover. This
1256    function does not return.
1257
1258 *******************************************************************************/
1259
1260 void FatalError(JNIEnv *env, const char *msg)
1261 {
1262         STATISTICS(jniinvokation());
1263
1264         throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1265 }
1266
1267
1268 /* PushLocalFrame **************************************************************
1269
1270    Creates a new local reference frame, in which at least a given
1271    number of local references can be created.
1272
1273 *******************************************************************************/
1274
1275 jint PushLocalFrame(JNIEnv* env, jint capacity)
1276 {
1277         STATISTICS(jniinvokation());
1278
1279         log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1280
1281         assert(0);
1282
1283         return 0;
1284 }
1285
1286 /* PopLocalFrame ***************************************************************
1287
1288    Pops off the current local reference frame, frees all the local
1289    references, and returns a local reference in the previous local
1290    reference frame for the given result object.
1291
1292 *******************************************************************************/
1293
1294 jobject PopLocalFrame(JNIEnv* env, jobject result)
1295 {
1296         STATISTICS(jniinvokation());
1297
1298         log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1299
1300         assert(0);
1301
1302         /* add local reference and return the value */
1303
1304         return NewLocalRef(env, NULL);
1305 }
1306
1307
1308 /* DeleteLocalRef **************************************************************
1309
1310    Deletes the local reference pointed to by localRef.
1311
1312 *******************************************************************************/
1313
1314 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1315 {
1316         java_objectheader *o;
1317         localref_table    *lrt;
1318         s4                 i;
1319
1320         STATISTICS(jniinvokation());
1321
1322         o = (java_objectheader *) localRef;
1323
1324         /* get local reference table (thread specific) */
1325
1326         lrt = LOCALREFTABLE;
1327
1328         /* remove the reference */
1329
1330         for (i = 0; i < lrt->capacity; i++) {
1331                 if (lrt->refs[i] == o) {
1332                         lrt->refs[i] = NULL;
1333                         lrt->used--;
1334
1335                         return;
1336                 }
1337         }
1338
1339         /* this should not happen */
1340
1341 /*      if (opt_checkjni) */
1342 /*      FatalError(env, "Bad global or local ref passed to JNI"); */
1343         log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1344 }
1345
1346
1347 /* IsSameObject ****************************************************************
1348
1349    Tests whether two references refer to the same Java object.
1350
1351 *******************************************************************************/
1352
1353 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1354 {
1355         STATISTICS(jniinvokation());
1356
1357         if (ref1 == ref2)
1358                 return JNI_TRUE;
1359         else
1360                 return JNI_FALSE;
1361 }
1362
1363
1364 /* NewLocalRef *****************************************************************
1365
1366    Creates a new local reference that refers to the same object as ref.
1367
1368 *******************************************************************************/
1369
1370 jobject NewLocalRef(JNIEnv *env, jobject ref)
1371 {
1372         localref_table *lrt;
1373         s4              i;
1374
1375         STATISTICS(jniinvokation());
1376
1377         if (ref == NULL)
1378                 return NULL;
1379
1380         /* get local reference table (thread specific) */
1381
1382         lrt = LOCALREFTABLE;
1383
1384         /* check if we have space for the requested reference */
1385
1386         if (lrt->used == lrt->capacity) {
1387 /*              throw_cacao_exception_exit(string_java_lang_InternalError, */
1388 /*                                                                 "Too many local references"); */
1389                 fprintf(stderr, "Too many local references");
1390                 assert(0);
1391         }
1392
1393         /* insert the reference */
1394
1395         for (i = 0; i < lrt->capacity; i++) {
1396                 if (lrt->refs[i] == NULL) {
1397                         lrt->refs[i] = (java_objectheader *) ref;
1398                         lrt->used++;
1399
1400                         return ref;
1401                 }
1402         }
1403
1404         /* should not happen, just to be sure */
1405
1406         assert(0);
1407
1408         /* keep compiler happy */
1409
1410         return NULL;
1411 }
1412
1413
1414 /* EnsureLocalCapacity *********************************************************
1415
1416    Ensures that at least a given number of local references can be
1417    created in the current thread
1418
1419 *******************************************************************************/
1420
1421 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1422 {
1423         localref_table *lrt;
1424
1425         STATISTICS(jniinvokation());
1426
1427         /* get local reference table (thread specific) */
1428
1429         lrt = LOCALREFTABLE;
1430
1431         /* check if capacity elements are available in the local references table */
1432
1433         if ((lrt->used + capacity) > lrt->capacity) {
1434                 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1435                 return -1;
1436         }
1437
1438         return 0;
1439 }
1440
1441
1442 /* AllocObject *****************************************************************
1443
1444    Allocates a new Java object without invoking any of the
1445    constructors for the object. Returns a reference to the object.
1446
1447 *******************************************************************************/
1448
1449 jobject AllocObject(JNIEnv *env, jclass clazz)
1450 {
1451         classinfo         *c;
1452         java_objectheader *o;
1453
1454         STATISTICS(jniinvokation());
1455
1456         c = (classinfo *) clazz;
1457
1458         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1459                 *exceptionptr =
1460                         new_exception_utfmessage(string_java_lang_InstantiationException,
1461                                                                          c->name);
1462                 return NULL;
1463         }
1464                 
1465         o = builtin_new(c);
1466
1467         return NewLocalRef(env, o);
1468 }
1469
1470
1471 /* NewObject *******************************************************************
1472
1473    Programmers place all arguments that are to be passed to the
1474    constructor immediately following the methodID
1475    argument. NewObject() accepts these arguments and passes them to
1476    the Java method that the programmer wishes to invoke.
1477
1478 *******************************************************************************/
1479
1480 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1481 {
1482         java_objectheader *o;
1483         methodinfo        *m;
1484         va_list            ap;
1485
1486         STATISTICS(jniinvokation());
1487
1488         m = (methodinfo *) methodID;
1489
1490         /* create object */
1491
1492         o = builtin_new(clazz);
1493         
1494         if (o == NULL)
1495                 return NULL;
1496
1497         /* call constructor */
1498
1499         va_start(ap, methodID);
1500         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
1501         va_end(ap);
1502
1503         return NewLocalRef(env, o);
1504 }
1505
1506
1507 /* NewObjectV ******************************************************************
1508
1509    Programmers place all arguments that are to be passed to the
1510    constructor in an args argument of type va_list that immediately
1511    follows the methodID argument. NewObjectV() accepts these
1512    arguments, and, in turn, passes them to the Java method that the
1513    programmer wishes to invoke.
1514
1515 *******************************************************************************/
1516
1517 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1518 {
1519         java_objectheader *o;
1520         methodinfo        *m;
1521
1522         STATISTICS(jniinvokation());
1523
1524         m = (methodinfo *) methodID;
1525
1526         /* create object */
1527
1528         o = builtin_new(clazz);
1529         
1530         if (o == NULL)
1531                 return NULL;
1532
1533         /* call constructor */
1534
1535         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
1536
1537         return NewLocalRef(env, o);
1538 }
1539
1540
1541 /* NewObjectA ***************************************************************** 
1542
1543    Programmers place all arguments that are to be passed to the
1544    constructor in an args array of jvalues that immediately follows
1545    the methodID argument. NewObjectA() accepts the arguments in this
1546    array, and, in turn, passes them to the Java method that the
1547    programmer wishes to invoke.
1548
1549 *******************************************************************************/
1550
1551 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1552 {
1553         java_objectheader *o;
1554         methodinfo        *m;
1555
1556         STATISTICS(jniinvokation());
1557
1558         m = (methodinfo *) methodID;
1559
1560         /* create object */
1561
1562         o = builtin_new(clazz);
1563         
1564         if (o == NULL)
1565                 return NULL;
1566
1567         /* call constructor */
1568
1569         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
1570
1571         return NewLocalRef(env, o);
1572 }
1573
1574
1575 /* GetObjectClass **************************************************************
1576
1577  Returns the class of an object.
1578
1579 *******************************************************************************/
1580
1581 jclass GetObjectClass(JNIEnv *env, jobject obj)
1582 {
1583         java_objectheader *o;
1584         classinfo         *c;
1585
1586         STATISTICS(jniinvokation());
1587
1588         o = (java_objectheader *) obj;
1589
1590         if ((o == NULL) || (o->vftbl == NULL))
1591                 return NULL;
1592
1593         c = o->vftbl->class;
1594
1595         return (jclass) NewLocalRef(env, (jobject) c);
1596 }
1597
1598
1599 /* IsInstanceOf ****************************************************************
1600
1601    Tests whether an object is an instance of a class.
1602
1603 *******************************************************************************/
1604
1605 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1606 {
1607         STATISTICS(jniinvokation());
1608
1609         return Java_java_lang_VMClass_isInstance(env,
1610                                                                                          NULL,
1611                                                                                          (java_lang_Class *) clazz,
1612                                                                                          (java_lang_Object *) obj);
1613 }
1614
1615
1616 /* Reflection Support *********************************************************/
1617
1618 /* FromReflectedMethod *********************************************************
1619
1620    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1621    object to a method ID.
1622   
1623 *******************************************************************************/
1624   
1625 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
1626 {
1627         methodinfo *mi;
1628         classinfo  *c;
1629         s4          slot;
1630
1631         STATISTICS(jniinvokation());
1632
1633         if (method == NULL)
1634                 return NULL;
1635         
1636         if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
1637                 java_lang_reflect_Method *rm;
1638
1639                 rm = (java_lang_reflect_Method *) method;
1640                 c = (classinfo *) (rm->declaringClass);
1641                 slot = rm->slot;
1642
1643         } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
1644                 java_lang_reflect_Constructor *rc;
1645
1646                 rc = (java_lang_reflect_Constructor *) method;
1647                 c = (classinfo *) (rc->clazz);
1648                 slot = rc->slot;
1649
1650         } else
1651                 return NULL;
1652
1653         mi = &(c->methods[slot]);
1654
1655         return (jmethodID) mi;
1656 }
1657
1658
1659 /* FromReflectedField **********************************************************
1660
1661    Converts a java.lang.reflect.Field to a field ID.
1662
1663 *******************************************************************************/
1664  
1665 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1666 {
1667         java_lang_reflect_Field *rf;
1668         classinfo               *c;
1669         fieldinfo               *f;
1670
1671         STATISTICS(jniinvokation());
1672
1673         rf = (java_lang_reflect_Field *) field;
1674
1675         if (rf == NULL)
1676                 return NULL;
1677
1678         c = (classinfo *) rf->declaringClass;
1679
1680         f = &(c->fields[rf->slot]);
1681
1682         return (jfieldID) f;
1683 }
1684
1685
1686 /* ToReflectedMethod ***********************************************************
1687
1688    Converts a method ID derived from cls to an instance of the
1689    java.lang.reflect.Method class or to an instance of the
1690    java.lang.reflect.Constructor class.
1691
1692 *******************************************************************************/
1693
1694 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1695 {
1696         STATISTICS(jniinvokation());
1697
1698         log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
1699
1700         return NULL;
1701 }
1702
1703
1704 /* ToReflectedField ************************************************************
1705
1706    Converts a field ID derived from cls to an instance of the
1707    java.lang.reflect.Field class.
1708
1709 *******************************************************************************/
1710
1711 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1712                                                  jboolean isStatic)
1713 {
1714         STATISTICS(jniinvokation());
1715
1716         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1717
1718         return NULL;
1719 }
1720
1721
1722 /* Calling Instance Methods ***************************************************/
1723
1724 /* GetMethodID *****************************************************************
1725
1726    Returns the method ID for an instance (nonstatic) method of a class
1727    or interface. The method may be defined in one of the clazz's
1728    superclasses and inherited by clazz. The method is determined by
1729    its name and signature.
1730
1731    GetMethodID() causes an uninitialized class to be initialized.
1732
1733 *******************************************************************************/
1734
1735 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1736                                           const char *sig)
1737 {
1738         classinfo  *c;
1739         utf        *uname;
1740         utf        *udesc;
1741         methodinfo *m;
1742
1743         STATISTICS(jniinvokation());
1744
1745         c = (classinfo *) clazz;
1746
1747         if (!c)
1748                 return NULL;
1749
1750         if (!(c->state & CLASS_INITIALIZED))
1751                 if (!initialize_class(c))
1752                         return NULL;
1753
1754         /* try to get the method of the class or one of it's superclasses */
1755
1756         uname = utf_new_char((char *) name);
1757         udesc = utf_new_char((char *) sig);
1758
1759         m = class_resolvemethod(clazz, uname, udesc);
1760
1761         if ((m == NULL) || (m->flags & ACC_STATIC)) {
1762                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1763
1764                 return NULL;
1765         }
1766
1767         return (jmethodID) m;
1768 }
1769
1770
1771 /* JNI-functions for calling instance methods *********************************/
1772
1773 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1774 {
1775         java_objectheader *o;
1776         methodinfo        *m;
1777         java_objectheader *ret;
1778         va_list            ap;
1779
1780         o = (java_objectheader *) obj;
1781         m = (methodinfo *) methodID;
1782
1783         va_start(ap, methodID);
1784         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
1785         va_end(ap);
1786
1787         return NewLocalRef(env, ret);
1788 }
1789
1790
1791 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1792 {
1793         java_objectheader *o;
1794         methodinfo        *m;
1795         java_objectheader *ret;
1796
1797         o = (java_objectheader *) obj;
1798         m = (methodinfo *) methodID;
1799
1800         ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
1801
1802         return NewLocalRef(env, ret);
1803 }
1804
1805
1806 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1807 {
1808         java_objectheader *o;
1809         methodinfo        *m;
1810         java_objectheader *ret;
1811
1812         o = (java_objectheader *) obj;
1813         m = (methodinfo *) methodID;
1814
1815         ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
1816
1817         return NewLocalRef(env, ret);
1818 }
1819
1820
1821 jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1822 {
1823         java_objectheader *o;
1824         methodinfo        *m;
1825         va_list            ap;
1826         jboolean           b;
1827
1828         o = (java_objectheader *) obj;
1829         m = (methodinfo *) methodID;
1830
1831         va_start(ap, methodID);
1832         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1833         va_end(ap);
1834
1835         return b;
1836 }
1837
1838
1839 jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1840 {
1841         java_objectheader *o;
1842         methodinfo        *m;
1843         jboolean           b;
1844
1845         o = (java_objectheader *) obj;
1846         m = (methodinfo *) methodID;
1847
1848         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1849
1850         return b;
1851 }
1852
1853
1854 jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1855 {
1856         log_text("JNI-Call: CallBooleanMethodA");
1857
1858         return 0;
1859 }
1860
1861
1862 jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1863 {
1864         java_objectheader *o;
1865         methodinfo        *m;
1866         va_list            ap;
1867         jbyte              b;
1868
1869         o = (java_objectheader *) obj;
1870         m = (methodinfo *) methodID;
1871
1872         va_start(ap, methodID);
1873         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1874         va_end(ap);
1875
1876         return b;
1877
1878 }
1879
1880 jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1881 {
1882         java_objectheader *o;
1883         methodinfo        *m;
1884         jbyte              b;
1885
1886         o = (java_objectheader *) obj;
1887         m = (methodinfo *) methodID;
1888
1889         b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1890
1891         return b;
1892 }
1893
1894
1895 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1896 {
1897         log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
1898
1899         return 0;
1900 }
1901
1902
1903 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1904 {
1905         java_objectheader *o;
1906         methodinfo        *m;
1907         va_list            ap;
1908         jchar              c;
1909
1910         o = (java_objectheader *) obj;
1911         m = (methodinfo *) methodID;
1912
1913         va_start(ap, methodID);
1914         c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1915         va_end(ap);
1916
1917         return c;
1918 }
1919
1920
1921 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1922 {
1923         java_objectheader *o;
1924         methodinfo        *m;
1925         jchar              c;
1926
1927         o = (java_objectheader *) obj;
1928         m = (methodinfo *) methodID;
1929
1930         c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1931
1932         return c;
1933 }
1934
1935
1936 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1937 {
1938         log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
1939
1940         return 0;
1941 }
1942
1943
1944 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1945 {
1946         java_objectheader *o;
1947         methodinfo        *m;
1948         va_list            ap;
1949         jshort             s;
1950
1951         o = (java_objectheader *) obj;
1952         m = (methodinfo *) methodID;
1953
1954         va_start(ap, methodID);
1955         s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1956         va_end(ap);
1957
1958         return s;
1959 }
1960
1961
1962 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1963 {
1964         java_objectheader *o;
1965         methodinfo        *m;
1966         jshort             s;
1967
1968         o = (java_objectheader *) obj;
1969         m = (methodinfo *) methodID;
1970
1971         s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
1972
1973         return s;
1974 }
1975
1976
1977 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1978 {
1979         log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
1980
1981         return 0;
1982 }
1983
1984
1985
1986 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1987 {
1988         java_objectheader *o;
1989         methodinfo        *m;
1990         va_list            ap;
1991         jint               i;
1992
1993         o = (java_objectheader *) obj;
1994         m = (methodinfo *) methodID;
1995
1996         va_start(ap, methodID);
1997         i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
1998         va_end(ap);
1999
2000         return i;
2001 }
2002
2003
2004 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2005 {
2006         java_objectheader *o;
2007         methodinfo        *m;
2008         jint               i;
2009
2010         o = (java_objectheader *) obj;
2011         m = (methodinfo *) methodID;
2012
2013         i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
2014
2015         return i;
2016 }
2017
2018
2019 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2020 {
2021         log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
2022
2023         return 0;
2024 }
2025
2026
2027
2028 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2029 {
2030         java_objectheader *o;
2031         methodinfo        *m;
2032         va_list            ap;
2033         jlong              l;
2034
2035         o = (java_objectheader *) obj;
2036         m = (methodinfo *) methodID;
2037
2038         va_start(ap, methodID);
2039         l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
2040         va_end(ap);
2041
2042         return l;
2043 }
2044
2045
2046 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2047 {
2048         java_objectheader *o;
2049         methodinfo        *m;
2050         jlong              l;
2051
2052         o = (java_objectheader *) obj;
2053         m = (methodinfo *) methodID;
2054
2055         l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
2056
2057         return l;
2058 }
2059
2060
2061 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2062 {
2063         log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
2064
2065         return 0;
2066 }
2067
2068
2069
2070 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2071 {
2072         java_objectheader *o;
2073         methodinfo        *m;
2074         va_list            ap;
2075         jfloat             f;
2076
2077         o = (java_objectheader *) obj;
2078         m = (methodinfo *) methodID;
2079
2080         va_start(ap, methodID);
2081         f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
2082         va_end(ap);
2083
2084         return f;
2085 }
2086
2087
2088 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2089 {
2090         java_objectheader *o;
2091         methodinfo        *m;
2092         jfloat             f;
2093
2094         o = (java_objectheader *) obj;
2095         m = (methodinfo *) methodID;
2096
2097         f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
2098
2099         return f;
2100 }
2101
2102
2103 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2104 {
2105         log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
2106
2107         return 0;
2108 }
2109
2110
2111
2112 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2113 {
2114         java_objectheader *o;
2115         methodinfo        *m;
2116         va_list            ap;
2117         jdouble            d;
2118
2119         o = (java_objectheader *) obj;
2120         m = (methodinfo *) methodID;
2121
2122         va_start(ap, methodID);
2123         d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
2124         va_end(ap);
2125
2126         return d;
2127 }
2128
2129
2130 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2131 {
2132         java_objectheader *o;
2133         methodinfo        *m;
2134         jdouble            d;
2135
2136         o = (java_objectheader *) obj;
2137         m = (methodinfo *) methodID;
2138
2139         d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
2140
2141         return d;
2142 }
2143
2144
2145 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2146 {
2147         log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
2148
2149         return 0;
2150 }
2151
2152
2153
2154 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
2155 {
2156         java_objectheader *o;
2157         methodinfo        *m;
2158         va_list            ap;
2159
2160         o = (java_objectheader *) obj;
2161         m = (methodinfo *) methodID;
2162
2163         va_start(ap, methodID);
2164         _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
2165         va_end(ap);
2166 }
2167
2168
2169 void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
2170 {
2171         java_objectheader *o;
2172         methodinfo        *m;
2173
2174         o = (java_objectheader *) obj;
2175         m = (methodinfo *) methodID;
2176
2177         _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
2178 }
2179
2180
2181 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
2182 {
2183         java_objectheader *o;
2184         methodinfo        *m;
2185
2186         o = (java_objectheader *) obj;
2187         m = (methodinfo *) methodID;
2188
2189         _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
2190 }
2191
2192
2193
2194 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2195 {
2196         java_objectheader *o;
2197         classinfo         *c;
2198         methodinfo        *m;
2199         java_objectheader *r;
2200         va_list            ap;
2201
2202         o = (java_objectheader *) obj;
2203         c = (classinfo *) clazz;
2204         m = (methodinfo *) methodID;
2205
2206         va_start(ap, methodID);
2207         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
2208         va_end(ap);
2209
2210         return NewLocalRef(env, r);
2211 }
2212
2213
2214 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2215 {
2216         java_objectheader *o;
2217         classinfo         *c;
2218         methodinfo        *m;
2219         java_objectheader *r;
2220
2221         o = (java_objectheader *) obj;
2222         c = (classinfo *) clazz;
2223         m = (methodinfo *) methodID;
2224
2225         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2226
2227         return NewLocalRef(env, r);
2228 }
2229
2230
2231 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2232 {
2233         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2234
2235         return NewLocalRef(env, NULL);
2236 }
2237
2238
2239
2240 jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2241 {
2242         java_objectheader *o;
2243         classinfo         *c;
2244         methodinfo        *m;
2245         va_list            ap;
2246         jboolean           b;
2247
2248         o = (java_objectheader *) obj;
2249         c = (classinfo *) clazz;
2250         m = (methodinfo *) methodID;
2251
2252         va_start(ap, methodID);
2253         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2254         va_end(ap);
2255
2256         return b;
2257 }
2258
2259
2260 jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2261 {
2262         java_objectheader *o;
2263         classinfo         *c;
2264         methodinfo        *m;
2265         jboolean           b;
2266
2267         o = (java_objectheader *) obj;
2268         c = (classinfo *) clazz;
2269         m = (methodinfo *) methodID;
2270
2271         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2272
2273         return b;
2274 }
2275
2276
2277 jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2278 {
2279         log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
2280
2281         return 0;
2282 }
2283
2284
2285 jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2286 {
2287         java_objectheader *o;
2288         classinfo         *c;
2289         methodinfo        *m;
2290         va_list            ap;
2291         jbyte              b;
2292
2293         o = (java_objectheader *) obj;
2294         c = (classinfo *) clazz;
2295         m = (methodinfo *) methodID;
2296
2297         va_start(ap, methodID);
2298         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2299         va_end(ap);
2300
2301         return b;
2302 }
2303
2304
2305 jbyte CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2306 {
2307         java_objectheader *o;
2308         classinfo         *c;
2309         methodinfo        *m;
2310         jbyte              b;
2311
2312         o = (java_objectheader *) obj;
2313         c = (classinfo *) clazz;
2314         m = (methodinfo *) methodID;
2315
2316         b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2317
2318         return b;
2319 }
2320
2321
2322 jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2323 {
2324         log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
2325
2326         return 0;
2327 }
2328
2329
2330
2331 jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2332 {
2333         java_objectheader *o;
2334         classinfo         *c;
2335         methodinfo        *m;
2336         va_list            ap;
2337         jchar              ch;
2338
2339         o = (java_objectheader *) obj;
2340         c = (classinfo *) clazz;
2341         m = (methodinfo *) methodID;
2342
2343         va_start(ap, methodID);
2344         ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2345         va_end(ap);
2346
2347         return ch;
2348 }
2349
2350
2351 jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2352 {
2353         java_objectheader *o;
2354         classinfo         *c;
2355         methodinfo        *m;
2356         jchar              ch;
2357
2358         o = (java_objectheader *) obj;
2359         c = (classinfo *) clazz;
2360         m = (methodinfo *) methodID;
2361
2362         ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2363
2364         return ch;
2365 }
2366
2367
2368 jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2369 {
2370         log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
2371
2372         return 0;
2373 }
2374
2375
2376
2377 jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2378 {
2379         java_objectheader *o;
2380         classinfo         *c;
2381         methodinfo        *m;
2382         va_list            ap;
2383         jshort             s;
2384
2385         o = (java_objectheader *) obj;
2386         c = (classinfo *) clazz;
2387         m = (methodinfo *) methodID;
2388
2389         va_start(ap, methodID);
2390         s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2391         va_end(ap);
2392
2393         return s;
2394 }
2395
2396
2397 jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2398 {
2399         java_objectheader *o;
2400         classinfo         *c;
2401         methodinfo        *m;
2402         jshort             s;
2403
2404         o = (java_objectheader *) obj;
2405         c = (classinfo *) clazz;
2406         m = (methodinfo *) methodID;
2407
2408         s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2409
2410         return s;
2411 }
2412
2413
2414 jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2415 {
2416         log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
2417
2418         return 0;
2419 }
2420
2421
2422
2423 jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2424 {
2425         java_objectheader *o;
2426         classinfo         *c;
2427         methodinfo        *m;
2428         va_list            ap;
2429         jint               i;
2430
2431         o = (java_objectheader *) obj;
2432         c = (classinfo *) clazz;
2433         m = (methodinfo *) methodID;
2434
2435         va_start(ap, methodID);
2436         i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
2437         va_end(ap);
2438
2439         return i;
2440 }
2441
2442
2443 jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2444 {
2445         java_objectheader *o;
2446         classinfo         *c;
2447         methodinfo        *m;
2448         jint               i;
2449
2450         o = (java_objectheader *) obj;
2451         c = (classinfo *) clazz;
2452         m = (methodinfo *) methodID;
2453
2454         i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
2455
2456         return i;
2457 }
2458
2459
2460 jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2461 {
2462         log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
2463
2464         return 0;
2465 }
2466
2467
2468
2469 jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2470 {
2471         java_objectheader *o;
2472         classinfo         *c;
2473         methodinfo        *m;
2474         va_list            ap;
2475         jlong              l;
2476
2477         o = (java_objectheader *) obj;
2478         c = (classinfo *) clazz;
2479         m = (methodinfo *) methodID;
2480
2481         va_start(ap, methodID);
2482         l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
2483         va_end(ap);
2484
2485         return l;
2486 }
2487
2488
2489 jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2490 {
2491         java_objectheader *o;
2492         classinfo         *c;
2493         methodinfo        *m;
2494         jlong              l;
2495
2496         o = (java_objectheader *) obj;
2497         c = (classinfo *) clazz;
2498         m = (methodinfo *) methodID;
2499
2500         l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
2501
2502         return l;
2503 }
2504
2505
2506 jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2507 {
2508         log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
2509
2510         return 0;
2511 }
2512
2513
2514
2515 jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2516 {
2517         java_objectheader *o;
2518         classinfo         *c;
2519         methodinfo        *m;
2520         va_list            ap;
2521         jfloat             f;
2522
2523         o = (java_objectheader *) obj;
2524         c = (classinfo *) clazz;
2525         m = (methodinfo *) methodID;
2526
2527         va_start(ap, methodID);
2528         f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
2529         va_end(ap);
2530
2531         return f;
2532 }
2533
2534
2535 jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2536 {
2537         java_objectheader *o;
2538         classinfo         *c;
2539         methodinfo        *m;
2540         jfloat             f;
2541
2542         o = (java_objectheader *) obj;
2543         c = (classinfo *) clazz;
2544         m = (methodinfo *) methodID;
2545
2546         f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
2547
2548         return f;
2549 }
2550
2551
2552 jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2553 {
2554         log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
2555
2556         return 0;
2557 }
2558
2559
2560
2561 jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2562 {
2563         java_objectheader *o;
2564         classinfo         *c;
2565         methodinfo        *m;
2566         va_list            ap;
2567         jdouble            d;
2568
2569         o = (java_objectheader *) obj;
2570         c = (classinfo *) clazz;
2571         m = (methodinfo *) methodID;
2572
2573         va_start(ap, methodID);
2574         d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
2575         va_end(ap);
2576
2577         return d;
2578 }
2579
2580
2581 jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2582 {
2583         java_objectheader *o;
2584         classinfo         *c;
2585         methodinfo        *m;
2586         jdouble            d;
2587
2588         o = (java_objectheader *) obj;
2589         c = (classinfo *) clazz;
2590         m = (methodinfo *) methodID;
2591
2592         d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
2593
2594         return d;
2595 }
2596
2597
2598 jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2599 {
2600         log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
2601
2602         return 0;
2603 }
2604
2605
2606
2607 void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2608 {
2609         java_objectheader *o;
2610         classinfo         *c;
2611         methodinfo        *m;
2612         va_list            ap;
2613
2614         o = (java_objectheader *) obj;
2615         c = (classinfo *) clazz;
2616         m = (methodinfo *) methodID;
2617
2618         va_start(ap, methodID);
2619         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2620         va_end(ap);
2621 }
2622
2623
2624 void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2625 {
2626         java_objectheader *o;
2627         classinfo         *c;
2628         methodinfo        *m;
2629
2630         o = (java_objectheader *) obj;
2631         c = (classinfo *) clazz;
2632         m = (methodinfo *) methodID;
2633
2634         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2635 }
2636
2637
2638 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2639 {       
2640         java_objectheader *o;
2641         classinfo         *c;
2642         methodinfo        *m;
2643
2644         o = (java_objectheader *) obj;
2645         c = (classinfo *) clazz;
2646         m = (methodinfo *) methodID;
2647
2648         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2649 }
2650
2651
2652 /* Accessing Fields of Objects ************************************************/
2653
2654 /* GetFieldID ******************************************************************
2655
2656    Returns the field ID for an instance (nonstatic) field of a
2657    class. The field is specified by its name and signature. The
2658    Get<type>Field and Set<type>Field families of accessor functions
2659    use field IDs to retrieve object fields.
2660
2661 *******************************************************************************/
2662
2663 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2664                                         const char *sig) 
2665 {
2666         fieldinfo *f;
2667         utf       *uname;
2668         utf       *udesc;
2669
2670         STATISTICS(jniinvokation());
2671
2672         uname = utf_new_char((char *) name);
2673         udesc = utf_new_char((char *) sig);
2674
2675         f = class_findfield(clazz, uname, udesc); 
2676         
2677         if (!f)
2678                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2679
2680         return (jfieldID) f;
2681 }
2682
2683
2684 /* Get<type>Field Routines *****************************************************
2685
2686    This family of accessor routines returns the value of an instance
2687    (nonstatic) field of an object. The field to access is specified by
2688    a field ID obtained by calling GetFieldID().
2689
2690 *******************************************************************************/
2691
2692 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2693 {
2694         java_objectheader *o;
2695
2696         STATISTICS(jniinvokation());
2697
2698         o = GET_FIELD(obj, java_objectheader*, fieldID);
2699
2700         return NewLocalRef(env, o);
2701 }
2702
2703
2704 jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
2705 {
2706         s4 i;
2707
2708         STATISTICS(jniinvokation());
2709
2710         i = GET_FIELD(obj, s4, fieldID);
2711
2712         return (jboolean) i;
2713 }
2714
2715
2716 jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
2717 {
2718         s4 i;
2719
2720         STATISTICS(jniinvokation());
2721
2722         i = GET_FIELD(obj, s4, fieldID);
2723
2724         return (jbyte) i;
2725 }
2726
2727
2728 jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
2729 {
2730         s4 i;
2731
2732         STATISTICS(jniinvokation());
2733
2734         i = GET_FIELD(obj, s4, fieldID);
2735
2736         return (jchar) i;
2737 }
2738
2739
2740 jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
2741 {
2742         s4 i;
2743
2744         STATISTICS(jniinvokation());
2745
2746         i = GET_FIELD(obj, s4, fieldID);
2747
2748         return (jshort) i;
2749 }
2750
2751
2752 jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
2753 {
2754         java_objectheader *o;
2755         fieldinfo         *f;
2756         s4                 i;
2757
2758         STATISTICS(jniinvokation());
2759
2760         o = (java_objectheader *) obj;
2761         f = (fieldinfo *) fieldID;
2762
2763         i = GET_FIELD(o, s4, f);
2764
2765         return i;
2766 }
2767
2768
2769 jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
2770 {
2771         s8 l;
2772
2773         STATISTICS(jniinvokation());
2774
2775         l = GET_FIELD(obj, s8, fieldID);
2776
2777         return l;
2778 }
2779
2780
2781 jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
2782 {
2783         float f;
2784
2785         STATISTICS(jniinvokation());
2786
2787         f = GET_FIELD(obj, float, fieldID);
2788
2789         return f;
2790 }
2791
2792
2793 jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
2794 {
2795         double d;
2796
2797         STATISTICS(jniinvokation());
2798
2799         d = GET_FIELD(obj, double, fieldID);
2800
2801         return d;
2802 }
2803
2804
2805 /* Set<type>Field Routines *****************************************************
2806
2807    This family of accessor routines sets the value of an instance
2808    (nonstatic) field of an object. The field to access is specified by
2809    a field ID obtained by calling GetFieldID().
2810
2811 *******************************************************************************/
2812
2813 void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
2814 {
2815         STATISTICS(jniinvokation());
2816
2817         SET_FIELD(obj, java_objectheader*, fieldID, value);
2818 }
2819
2820
2821 void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
2822 {
2823         STATISTICS(jniinvokation());
2824
2825         SET_FIELD(obj, s4, fieldID, value);
2826 }
2827
2828
2829 void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
2830 {
2831         STATISTICS(jniinvokation());
2832
2833         SET_FIELD(obj, s4, fieldID, value);
2834 }
2835
2836
2837 void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
2838 {
2839         STATISTICS(jniinvokation());
2840
2841         SET_FIELD(obj, s4, fieldID, value);
2842 }
2843
2844
2845 void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
2846 {
2847         STATISTICS(jniinvokation());
2848
2849         SET_FIELD(obj, s4, fieldID, value);
2850 }
2851
2852
2853 void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
2854 {
2855         STATISTICS(jniinvokation());
2856
2857         SET_FIELD(obj, s4, fieldID, value);
2858 }
2859
2860
2861 void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
2862 {
2863         STATISTICS(jniinvokation());
2864
2865         SET_FIELD(obj, s8, fieldID, value);
2866 }
2867
2868
2869 void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
2870 {
2871         STATISTICS(jniinvokation());
2872
2873         SET_FIELD(obj, float, fieldID, value);
2874 }
2875
2876
2877 void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
2878 {
2879         STATISTICS(jniinvokation());
2880
2881         SET_FIELD(obj, double, fieldID, value);
2882 }
2883
2884
2885 /* Calling Static Methods *****************************************************/
2886
2887 /* GetStaticMethodID ***********************************************************
2888
2889    Returns the method ID for a static method of a class. The method is
2890    specified by its name and signature.
2891
2892    GetStaticMethodID() causes an uninitialized class to be
2893    initialized.
2894
2895 *******************************************************************************/
2896
2897 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2898                                                         const char *sig)
2899 {
2900         classinfo  *c;
2901         utf        *uname;
2902         utf        *udesc;
2903         methodinfo *m;
2904
2905         STATISTICS(jniinvokation());
2906
2907         c = (classinfo *) clazz;
2908
2909         if (!c)
2910                 return NULL;
2911
2912         if (!(c->state & CLASS_INITIALIZED))
2913                 if (!initialize_class(c))
2914                         return NULL;
2915
2916         /* try to get the static method of the class */
2917
2918         uname = utf_new_char((char *) name);
2919         udesc = utf_new_char((char *) sig);
2920
2921         m = class_resolvemethod(c, uname, udesc);
2922
2923         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2924                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2925
2926                 return NULL;
2927         }
2928
2929         return (jmethodID) m;
2930 }
2931
2932
2933 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2934 {
2935         methodinfo        *m;
2936         java_objectheader *o;
2937         va_list            ap;
2938
2939         m = (methodinfo *) methodID;
2940
2941         va_start(ap, methodID);
2942         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2943         va_end(ap);
2944
2945         return NewLocalRef(env, o);
2946 }
2947
2948
2949 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2950 {
2951         methodinfo        *m;
2952         java_objectheader *o;
2953
2954         m = (methodinfo *) methodID;
2955
2956         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2957
2958         return NewLocalRef(env, o);
2959 }
2960
2961
2962 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2963 {
2964         methodinfo        *m;
2965         java_objectheader *o;
2966
2967         m = (methodinfo *) methodID;
2968
2969         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2970
2971         return NewLocalRef(env, o);
2972 }
2973
2974
2975 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2976 {
2977         methodinfo *m;
2978         va_list     ap;
2979         jboolean    b;
2980
2981         m = (methodinfo *) methodID;
2982
2983         va_start(ap, methodID);
2984         b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
2985         va_end(ap);
2986
2987         return b;
2988 }
2989
2990
2991 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2992 {
2993         methodinfo *m;
2994         jboolean    b;
2995
2996         m = (methodinfo *) methodID;
2997
2998         b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
2999
3000         return b;
3001 }
3002
3003
3004 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3005 {
3006         log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
3007
3008         return 0;
3009 }
3010
3011
3012 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3013 {
3014         methodinfo *m;
3015         va_list     ap;
3016         jbyte       b;
3017
3018         m = (methodinfo *) methodID;
3019
3020         va_start(ap, methodID);
3021         b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3022         va_end(ap);
3023
3024         return b;
3025 }
3026
3027
3028 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3029 {
3030         methodinfo *m;
3031         jbyte       b;
3032
3033         m = (methodinfo *) methodID;
3034
3035         b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3036
3037         return b;
3038 }
3039
3040
3041 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3042 {
3043         log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
3044
3045         return 0;
3046 }
3047
3048
3049 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3050 {
3051         methodinfo *m;
3052         va_list     ap;
3053         jchar       c;
3054
3055         m = (methodinfo *) methodID;
3056
3057         va_start(ap, methodID);
3058         c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3059         va_end(ap);
3060
3061         return c;
3062 }
3063
3064
3065 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3066 {
3067         methodinfo *m;
3068         jchar       c;
3069
3070         m = (methodinfo *) methodID;
3071
3072         c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3073
3074         return c;
3075 }
3076
3077
3078 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3079 {
3080         log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
3081
3082         return 0;
3083 }
3084
3085
3086 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3087 {
3088         methodinfo *m;
3089         va_list     ap;
3090         jshort      s;
3091
3092         m = (methodinfo *) methodID;
3093
3094         va_start(ap, methodID);
3095         s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3096         va_end(ap);
3097
3098         return s;
3099 }
3100
3101
3102 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3103 {
3104         methodinfo *m;
3105         jshort      s;
3106
3107         m = (methodinfo *) methodID;
3108
3109         s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3110
3111         return s;
3112 }
3113
3114
3115 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3116 {
3117         log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
3118
3119         return 0;
3120 }
3121
3122
3123 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3124 {
3125         methodinfo *m;
3126         va_list     ap;
3127         jint        i;
3128
3129         m = (methodinfo *) methodID;
3130
3131         va_start(ap, methodID);
3132         i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
3133         va_end(ap);
3134
3135         return i;
3136 }
3137
3138
3139 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3140 {
3141         methodinfo *m;
3142         jint        i;
3143
3144         m = (methodinfo *) methodID;
3145
3146         i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
3147
3148         return i;
3149 }
3150
3151
3152 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3153 {
3154         log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
3155
3156         return 0;
3157 }
3158
3159
3160 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3161 {
3162         methodinfo *m;
3163         va_list     ap;
3164         jlong       l;
3165
3166         m = (methodinfo *) methodID;
3167
3168         va_start(ap, methodID);
3169         l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
3170         va_end(ap);
3171
3172         return l;
3173 }
3174
3175
3176 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
3177                                                         va_list args)
3178 {
3179         methodinfo *m;
3180         jlong       l;
3181         
3182         m = (methodinfo *) methodID;
3183
3184         l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
3185
3186         return l;
3187 }
3188
3189
3190 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3191 {
3192         log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
3193
3194         return 0;
3195 }
3196
3197
3198
3199 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3200 {
3201         methodinfo *m;
3202         va_list     ap;
3203         jfloat      f;
3204
3205         m = (methodinfo *) methodID;
3206
3207         va_start(ap, methodID);
3208         f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
3209         va_end(ap);
3210
3211         return f;
3212 }
3213
3214
3215 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3216 {
3217         methodinfo *m;
3218         jfloat      f;
3219
3220         m = (methodinfo *) methodID;
3221
3222         f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
3223
3224         return f;
3225 }
3226
3227
3228 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3229 {
3230         log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
3231
3232         return 0;
3233 }
3234
3235
3236 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3237 {
3238         methodinfo *m;
3239         va_list     ap;
3240         jdouble     d;
3241
3242         m = (methodinfo *) methodID;
3243
3244         va_start(ap, methodID);
3245         d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
3246         va_end(ap);
3247
3248         return d;
3249 }
3250
3251
3252 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3253 {
3254         methodinfo *m;
3255         jdouble     d;
3256
3257         m = (methodinfo *) methodID;
3258
3259         d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
3260
3261         return d;
3262 }
3263
3264
3265 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
3266 {
3267         log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
3268
3269         return 0;
3270 }
3271
3272
3273 void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
3274 {
3275         methodinfo *m;
3276         va_list     ap;
3277
3278         m = (methodinfo *) methodID;
3279
3280         va_start(ap, methodID);
3281         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
3282         va_end(ap);
3283 }
3284
3285
3286 void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
3287 {
3288         methodinfo *m;
3289
3290         m = (methodinfo *) methodID;
3291
3292         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
3293 }
3294
3295
3296 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
3297 {
3298         methodinfo *m;
3299
3300         m = (methodinfo *) methodID;
3301
3302         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
3303 }
3304
3305
3306 /* Accessing Static Fields ****************************************************/
3307
3308 /* GetStaticFieldID ************************************************************
3309
3310    Returns the field ID for a static field of a class. The field is
3311    specified by its name and signature. The GetStatic<type>Field and
3312    SetStatic<type>Field families of accessor functions use field IDs
3313    to retrieve static fields.
3314
3315 *******************************************************************************/
3316
3317 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
3318 {
3319         fieldinfo *f;
3320
3321         STATISTICS(jniinvokation());
3322
3323         f = class_findfield(clazz,
3324                                                 utf_new_char((char *) name),
3325                                                 utf_new_char((char *) sig));
3326         
3327         if (f == NULL)
3328                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
3329
3330         return (jfieldID) f;
3331 }
3332
3333
3334 /* GetStatic<type>Field ********************************************************
3335
3336    This family of accessor routines returns the value of a static
3337    field of an object.
3338
3339 *******************************************************************************/
3340
3341 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3342 {
3343         classinfo *c;
3344         fieldinfo *f;
3345
3346         STATISTICS(jniinvokation());
3347
3348         c = (classinfo *) clazz;
3349         f = (fieldinfo *) fieldID;
3350
3351         if (!(c->state & CLASS_INITIALIZED))
3352                 if (!initialize_class(c))
3353                         return NULL;
3354
3355         return NewLocalRef(env, f->value.a);
3356 }
3357
3358
3359 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3360 {
3361         classinfo *c;
3362         fieldinfo *f;
3363
3364         STATISTICS(jniinvokation());
3365
3366         c = (classinfo *) clazz;
3367         f = (fieldinfo *) fieldID;
3368
3369         if (!(c->state & CLASS_INITIALIZED))
3370                 if (!initialize_class(c))
3371                         return false;
3372
3373         return f->value.i;
3374 }
3375
3376
3377 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3378 {
3379         classinfo *c;
3380         fieldinfo *f;
3381
3382         STATISTICS(jniinvokation());
3383
3384         c = (classinfo *) clazz;
3385         f = (fieldinfo *) fieldID;
3386
3387         if (!(c->state & CLASS_INITIALIZED))
3388                 if (!initialize_class(c))
3389                         return 0;
3390
3391         return f->value.i;
3392 }
3393
3394
3395 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3396 {
3397         classinfo *c;
3398         fieldinfo *f;
3399
3400         STATISTICS(jniinvokation());
3401
3402         c = (classinfo *) clazz;
3403         f = (fieldinfo *) fieldID;
3404
3405         if (!(c->state & CLASS_INITIALIZED))
3406                 if (!initialize_class(c))
3407                         return 0;
3408
3409         return f->value.i;
3410 }
3411
3412
3413 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3414 {
3415         classinfo *c;
3416         fieldinfo *f;
3417
3418         STATISTICS(jniinvokation());
3419
3420         c = (classinfo *) clazz;
3421         f = (fieldinfo *) fieldID;
3422
3423         if (!(c->state & CLASS_INITIALIZED))
3424                 if (!initialize_class(c))
3425                         return 0;
3426
3427         return f->value.i;
3428 }
3429
3430
3431 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3432 {
3433         classinfo *c;
3434         fieldinfo *f;
3435
3436         STATISTICS(jniinvokation());
3437
3438         c = (classinfo *) clazz;
3439         f = (fieldinfo *) fieldID;
3440
3441         if (!(c->state & CLASS_INITIALIZED))
3442                 if (!initialize_class(c))
3443                         return 0;
3444
3445         return f->value.i;
3446 }
3447
3448
3449 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3450 {
3451         classinfo *c;
3452         fieldinfo *f;
3453
3454         STATISTICS(jniinvokation());
3455
3456         c = (classinfo *) clazz;
3457         f = (fieldinfo *) fieldID;
3458
3459         if (!(c->state & CLASS_INITIALIZED))
3460                 if (!initialize_class(c))
3461                         return 0;
3462
3463         return f->value.l;
3464 }
3465
3466
3467 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3468 {
3469         classinfo *c;
3470         fieldinfo *f;
3471
3472         STATISTICS(jniinvokation());
3473
3474         c = (classinfo *) clazz;
3475         f = (fieldinfo *) fieldID;
3476
3477         if (!(c->state & CLASS_INITIALIZED))
3478                 if (!initialize_class(c))
3479                         return 0.0;
3480
3481         return f->value.f;
3482 }
3483
3484
3485 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
3486 {
3487         classinfo *c;
3488         fieldinfo *f;
3489
3490         STATISTICS(jniinvokation());
3491
3492         c = (classinfo *) clazz;
3493         f = (fieldinfo *) fieldID;
3494
3495         if (!(c->state & CLASS_INITIALIZED))
3496                 if (!initialize_class(c))
3497                         return 0.0;
3498
3499         return f->value.d;
3500 }
3501
3502
3503 /*  SetStatic<type>Field *******************************************************
3504
3505         This family of accessor routines sets the value of a static field
3506         of an object.
3507
3508 *******************************************************************************/
3509
3510 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
3511 {
3512         classinfo *c;
3513         fieldinfo *f;
3514
3515         STATISTICS(jniinvokation());
3516
3517         c = (classinfo *) clazz;
3518         f = (fieldinfo *) fieldID;
3519
3520         if (!(c->state & CLASS_INITIALIZED))
3521                 if (!initialize_class(c))
3522                         return;
3523
3524         f->value.a = value;
3525 }
3526
3527
3528 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
3529 {
3530         classinfo *c;
3531         fieldinfo *f;
3532
3533         STATISTICS(jniinvokation());
3534
3535         c = (classinfo *) clazz;
3536         f = (fieldinfo *) fieldID;
3537
3538         if (!(c->state & CLASS_INITIALIZED))
3539                 if (!initialize_class(c))
3540                         return;
3541
3542         f->value.i = value;
3543 }
3544
3545
3546 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
3547 {
3548         classinfo *c;
3549         fieldinfo *f;
3550
3551         STATISTICS(jniinvokation());
3552
3553         c = (classinfo *) clazz;
3554         f = (fieldinfo *) fieldID;
3555
3556         if (!(c->state & CLASS_INITIALIZED))
3557                 if (!initialize_class(c))
3558                         return;
3559
3560         f->value.i = value;
3561 }
3562
3563
3564 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
3565 {
3566         classinfo *c;
3567         fieldinfo *f;
3568
3569         STATISTICS(jniinvokation());
3570
3571         c = (classinfo *) clazz;
3572         f = (fieldinfo *) fieldID;
3573
3574         if (!(c->state & CLASS_INITIALIZED))
3575                 if (!initialize_class(c))
3576                         return;
3577
3578         f->value.i = value;
3579 }
3580
3581
3582 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
3583 {
3584         classinfo *c;
3585         fieldinfo *f;
3586
3587         STATISTICS(jniinvokation());
3588
3589         c = (classinfo *) clazz;
3590         f = (fieldinfo *) fieldID;
3591
3592         if (!(c->state & CLASS_INITIALIZED))
3593                 if (!initialize_class(c))
3594                         return;
3595
3596         f->value.i = value;
3597 }
3598
3599
3600 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
3601 {
3602         classinfo *c;
3603         fieldinfo *f;
3604
3605         STATISTICS(jniinvokation());
3606
3607         c = (classinfo *) clazz;
3608         f = (fieldinfo *) fieldID;
3609
3610         if (!(c->state & CLASS_INITIALIZED))
3611                 if (!initialize_class(c))
3612                         return;
3613
3614         f->value.i = value;
3615 }
3616
3617
3618 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
3619 {
3620         classinfo *c;
3621         fieldinfo *f;
3622
3623         STATISTICS(jniinvokation());
3624
3625         c = (classinfo *) clazz;
3626         f = (fieldinfo *) fieldID;
3627
3628         if (!(c->state & CLASS_INITIALIZED))
3629                 if (!initialize_class(c))
3630                         return;
3631
3632         f->value.l = value;
3633 }
3634
3635
3636 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
3637 {
3638         classinfo *c;
3639         fieldinfo *f;
3640
3641         STATISTICS(jniinvokation());
3642
3643         c = (classinfo *) clazz;
3644         f = (fieldinfo *) fieldID;
3645
3646         if (!(c->state & CLASS_INITIALIZED))
3647                 if (!initialize_class(c))
3648                         return;
3649
3650         f->value.f = value;
3651 }
3652
3653
3654 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
3655 {
3656         classinfo *c;
3657         fieldinfo *f;
3658
3659         STATISTICS(jniinvokation());
3660
3661         c = (classinfo *) clazz;
3662         f = (fieldinfo *) fieldID;
3663
3664         if (!(c->state & CLASS_INITIALIZED))
3665                 if (!initialize_class(c))
3666                         return;
3667
3668         f->value.d = value;
3669 }
3670
3671
3672 /* String Operations **********************************************************/
3673
3674 /* NewString *******************************************************************
3675
3676    Create new java.lang.String object from an array of Unicode
3677    characters.
3678
3679 *******************************************************************************/
3680
3681 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
3682 {
3683         java_lang_String *s;
3684         java_chararray   *a;
3685         u4                i;
3686
3687         STATISTICS(jniinvokation());
3688         
3689         s = (java_lang_String *) builtin_new(class_java_lang_String);
3690         a = builtin_newarray_char(len);
3691
3692         /* javastring or characterarray could not be created */
3693         if (!a || !s)
3694                 return NULL;
3695
3696         /* copy text */
3697         for (i = 0; i < len; i++)
3698                 a->data[i] = buf[i];
3699
3700         s->value = a;
3701         s->offset = 0;
3702         s->count = len;
3703
3704         return (jstring) NewLocalRef(env, (jobject) s);
3705 }
3706
3707
3708 static jchar emptyStringJ[]={0,0};
3709
3710 /* GetStringLength *************************************************************
3711
3712    Returns the length (the count of Unicode characters) of a Java
3713    string.
3714
3715 *******************************************************************************/
3716
3717 jsize GetStringLength(JNIEnv *env, jstring str)
3718 {
3719         return ((java_lang_String *) str)->count;
3720 }
3721
3722
3723 /********************  convertes javastring to u2-array ****************************/
3724         
3725 u2 *javastring_tou2(jstring so) 
3726 {
3727         java_lang_String *s;
3728         java_chararray   *a;
3729         u2               *stringbuffer;
3730         u4                i;
3731
3732         STATISTICS(jniinvokation());
3733         
3734         s = (java_lang_String *) so;
3735
3736         if (!s)
3737                 return NULL;
3738
3739         a = s->value;
3740
3741         if (!a)
3742                 return NULL;
3743
3744         /* allocate memory */
3745
3746         stringbuffer = MNEW(u2, s->count + 1);
3747
3748         /* copy text */
3749
3750         for (i = 0; i < s->count; i++)
3751                 stringbuffer[i] = a->data[s->offset + i];
3752         
3753         /* terminate string */
3754
3755         stringbuffer[i] = '\0';
3756
3757         return stringbuffer;
3758 }
3759
3760
3761 /* GetStringChars **************************************************************
3762
3763    Returns a pointer to the array of Unicode characters of the
3764    string. This pointer is valid until ReleaseStringchars() is called.
3765
3766 *******************************************************************************/
3767
3768 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
3769 {       
3770         jchar *jc;
3771
3772         STATISTICS(jniinvokation());
3773
3774         jc = javastring_tou2(str);
3775
3776         if (jc) {
3777                 if (isCopy)
3778                         *isCopy = JNI_TRUE;
3779
3780                 return jc;
3781         }
3782
3783         if (isCopy)
3784                 *isCopy = JNI_TRUE;
3785
3786         return emptyStringJ;
3787 }
3788
3789
3790 /* ReleaseStringChars **********************************************************
3791
3792    Informs the VM that the native code no longer needs access to
3793    chars. The chars argument is a pointer obtained from string using
3794    GetStringChars().
3795
3796 *******************************************************************************/
3797
3798 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
3799 {
3800         STATISTICS(jniinvokation());
3801
3802         if (chars == emptyStringJ)
3803                 return;
3804
3805         MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
3806 }
3807
3808
3809 /* NewStringUTF ****************************************************************
3810
3811    Constructs a new java.lang.String object from an array of UTF-8 characters.
3812
3813 *******************************************************************************/
3814
3815 jstring NewStringUTF(JNIEnv *env, const char *bytes)
3816 {
3817         java_lang_String *s;
3818
3819         STATISTICS(jniinvokation());
3820
3821         s = javastring_new(utf_new_char(bytes));
3822
3823     return (jstring) NewLocalRef(env, (jobject) s);
3824 }
3825
3826
3827 /****************** returns the utf8 length in bytes of a string *******************/
3828
3829 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3830 {   
3831     java_lang_String *s = (java_lang_String*) string;
3832
3833         STATISTICS(jniinvokation());
3834
3835     return (jsize) u2_utflength(s->value->data, s->count); 
3836 }
3837
3838
3839 /* GetStringUTFChars ***********************************************************
3840
3841    Returns a pointer to an array of UTF-8 characters of the
3842    string. This array is valid until it is released by
3843    ReleaseStringUTFChars().
3844
3845 *******************************************************************************/
3846
3847 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3848 {
3849         utf *u;
3850
3851         STATISTICS(jniinvokation());
3852
3853         if (!string)
3854                 return "";
3855
3856         if (isCopy)
3857                 *isCopy = JNI_TRUE;
3858         
3859         u = javastring_toutf((java_lang_String *) string, false);
3860
3861         if (u)
3862                 return u->text;
3863
3864         return "";
3865 }
3866
3867
3868 /* ReleaseStringUTFChars *******************************************************
3869
3870    Informs the VM that the native code no longer needs access to
3871    utf. The utf argument is a pointer derived from string using
3872    GetStringUTFChars().
3873
3874 *******************************************************************************/
3875
3876 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3877 {
3878         STATISTICS(jniinvokation());
3879
3880     /* XXX we don't release utf chars right now, perhaps that should be done 
3881            later. Since there is always one reference the garbage collector will
3882            never get them */
3883 }
3884
3885
3886 /* Array Operations ***********************************************************/
3887
3888 /* GetArrayLength **************************************************************
3889
3890    Returns the number of elements in the array.
3891
3892 *******************************************************************************/
3893
3894 jsize GetArrayLength(JNIEnv *env, jarray array)
3895 {
3896         java_arrayheader *a;
3897
3898         STATISTICS(jniinvokation());
3899
3900         a = (java_arrayheader *) array;
3901
3902         return a->size;
3903 }
3904
3905
3906 /* NewObjectArray **************************************************************
3907
3908    Constructs a new array holding objects in class elementClass. All
3909    elements are initially set to initialElement.
3910
3911 *******************************************************************************/
3912
3913 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3914 {
3915         java_objectarray *oa;
3916         s4                i;
3917
3918         STATISTICS(jniinvokation());
3919
3920         if (length < 0) {
3921                 exceptions_throw_negativearraysizeexception();
3922                 return NULL;
3923         }
3924
3925     oa = builtin_anewarray(length, elementClass);
3926
3927         if (!oa)
3928                 return NULL;
3929
3930         /* set all elements to initialElement */
3931
3932         for (i = 0; i < length; i++)
3933                 oa->data[i] = initialElement;
3934
3935         return (jobjectArray) NewLocalRef(env, (jobject) oa);
3936 }
3937
3938
3939 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3940 {
3941         java_objectarray *oa;
3942         jobject           o;
3943
3944         STATISTICS(jniinvokation());
3945
3946         oa = (java_objectarray *) array;
3947
3948         if (index >= oa->header.size) {
3949                 exceptions_throw_arrayindexoutofboundsexception();
3950                 return NULL;
3951         }
3952
3953         o = oa->data[index];
3954
3955         return NewLocalRef(env, o);
3956 }
3957
3958
3959 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3960 {
3961         java_objectarray  *oa;
3962         java_objectheader *o;
3963
3964         STATISTICS(jniinvokation());
3965
3966         oa = (java_objectarray *) array;
3967         o  = (java_objectheader *) val;
3968
3969         if (index >= oa->header.size) {
3970                 exceptions_throw_arrayindexoutofboundsexception();
3971                 return;
3972         }
3973
3974         /* check if the class of value is a subclass of the element class
3975            of the array */
3976
3977         if (!builtin_canstore(oa, o)) {
3978                 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3979
3980                 return;
3981         }
3982
3983         oa->data[index] = val;
3984 }
3985
3986
3987 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3988 {
3989         java_booleanarray *ba;
3990
3991         STATISTICS(jniinvokation());
3992
3993         if (len < 0) {
3994                 exceptions_throw_negativearraysizeexception();
3995                 return NULL;
3996         }
3997
3998         ba = builtin_newarray_boolean(len);
3999
4000         return (jbooleanArray) NewLocalRef(env, (jobject) ba);
4001 }
4002
4003
4004 jbyteArray NewByteArray(JNIEnv *env, jsize len)
4005 {
4006         java_bytearray *ba;
4007
4008         STATISTICS(jniinvokation());
4009
4010         if (len < 0) {
4011                 exceptions_throw_negativearraysizeexception();
4012                 return NULL;
4013         }
4014
4015         ba = builtin_newarray_byte(len);
4016
4017         return (jbyteArray) NewLocalRef(env, (jobject) ba);
4018 }
4019
4020
4021 jcharArray NewCharArray(JNIEnv *env, jsize len)
4022 {
4023         java_chararray *ca;
4024
4025         STATISTICS(jniinvokation());
4026
4027         if (len < 0) {
4028                 exceptions_throw_negativearraysizeexception();
4029                 return NULL;
4030         }
4031
4032         ca = builtin_newarray_char(len);
4033
4034         return (jcharArray) NewLocalRef(env, (jobject) ca);
4035 }
4036
4037
4038 jshortArray NewShortArray(JNIEnv *env, jsize len)
4039 {
4040         java_shortarray *sa;
4041
4042         STATISTICS(jniinvokation());
4043
4044         if (len < 0) {
4045                 exceptions_throw_negativearraysizeexception();
4046                 return NULL;
4047         }
4048
4049         sa = builtin_newarray_short(len);
4050
4051         return (jshortArray) NewLocalRef(env, (jobject) sa);
4052 }
4053
4054
4055 jintArray NewIntArray(JNIEnv *env, jsize len)
4056 {
4057         java_intarray *ia;
4058
4059         STATISTICS(jniinvokation());
4060
4061         if (len < 0) {
4062                 exceptions_throw_negativearraysizeexception();
4063                 return NULL;
4064         }
4065
4066         ia = builtin_newarray_int(len);
4067
4068         return (jintArray) NewLocalRef(env, (jobject) ia);
4069 }
4070
4071
4072 jlongArray NewLongArray(JNIEnv *env, jsize len)
4073 {
4074         java_longarray *la;
4075
4076         STATISTICS(jniinvokation());
4077
4078         if (len < 0) {
4079                 exceptions_throw_negativearraysizeexception();
4080                 return NULL;
4081         }
4082
4083         la = builtin_newarray_long(len);
4084
4085         return (jlongArray) NewLocalRef(env, (jobject) la);
4086 }
4087
4088
4089 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
4090 {
4091         java_floatarray *fa;
4092
4093         STATISTICS(jniinvokation());
4094
4095         if (len < 0) {
4096                 exceptions_throw_negativearraysizeexception();
4097                 return NULL;
4098         }
4099
4100         fa = builtin_newarray_float(len);
4101
4102         return (jfloatArray) NewLocalRef(env, (jobject) fa);
4103 }
4104
4105
4106 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
4107 {
4108         java_doublearray *da;
4109
4110         STATISTICS(jniinvokation());
4111
4112         if (len < 0) {
4113                 exceptions_throw_negativearraysizeexception();
4114                 return NULL;
4115         }
4116
4117         da = builtin_newarray_double(len);
4118
4119         return (jdoubleArray) NewLocalRef(env, (jobject) da);
4120 }
4121
4122
4123 /* Get<PrimitiveType>ArrayElements *********************************************
4124
4125    A family of functions that returns the body of the primitive array.
4126
4127 *******************************************************************************/
4128
4129 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4130                                                                   jboolean *isCopy)
4131 {
4132         java_booleanarray *ba;
4133
4134         STATISTICS(jniinvokation());
4135
4136         ba = (java_booleanarray *) array;
4137
4138         if (isCopy)
4139                 *isCopy = JNI_FALSE;
4140
4141         return ba->data;
4142 }
4143
4144
4145 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
4146 {
4147         java_bytearray *ba;
4148
4149         STATISTICS(jniinvokation());
4150
4151         ba = (java_bytearray *) array;
4152
4153         if (isCopy)
4154                 *isCopy = JNI_FALSE;
4155
4156         return ba->data;
4157 }
4158
4159
4160 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
4161 {
4162         java_chararray *ca;
4163
4164         STATISTICS(jniinvokation());
4165
4166         ca = (java_chararray *) array;
4167
4168         if (isCopy)
4169                 *isCopy = JNI_FALSE;
4170
4171         return ca->data;
4172 }
4173
4174
4175 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
4176 {
4177         java_shortarray *sa;
4178
4179         STATISTICS(jniinvokation());
4180
4181         sa = (java_shortarray *) array;
4182
4183         if (isCopy)
4184                 *isCopy = JNI_FALSE;
4185
4186         return sa->data;
4187 }
4188
4189
4190 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
4191 {
4192         java_intarray *ia;
4193
4194         STATISTICS(jniinvokation());
4195
4196         ia = (java_intarray *) array;
4197
4198         if (isCopy)
4199                 *isCopy = JNI_FALSE;
4200
4201         return ia->data;
4202 }
4203
4204
4205 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
4206 {
4207         java_longarray *la;
4208
4209         STATISTICS(jniinvokation());
4210
4211         la = (java_longarray *) array;
4212
4213         if (isCopy)
4214                 *isCopy = JNI_FALSE;
4215
4216         /* We cast this one to prevent a compiler warning on 64-bit
4217            systems since GNU Classpath typedef jlong to long long. */
4218
4219         return (jlong *) la->data;
4220 }
4221
4222
4223 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
4224 {
4225         java_floatarray *fa;
4226
4227         STATISTICS(jniinvokation());
4228
4229         fa = (java_floatarray *) array;
4230
4231         if (isCopy)
4232                 *isCopy = JNI_FALSE;
4233
4234         return fa->data;
4235 }
4236
4237
4238 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4239                                                                 jboolean *isCopy)
4240 {
4241         java_doublearray *da;
4242
4243         STATISTICS(jniinvokation());
4244
4245         da = (java_doublearray *) array;
4246
4247         if (isCopy)
4248                 *isCopy = JNI_FALSE;
4249
4250         return da->data;
4251 }
4252
4253
4254 /* Release<PrimitiveType>ArrayElements *****************************************
4255
4256    A family of functions that informs the VM that the native code no
4257    longer needs access to elems. The elems argument is a pointer
4258    derived from array using the corresponding
4259    Get<PrimitiveType>ArrayElements() function. If necessary, this
4260    function copies back all changes made to elems to the original
4261    array.
4262
4263 *******************************************************************************/
4264
4265 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4266                                                                  jboolean *elems, jint mode)
4267 {
4268         java_booleanarray *ba;
4269
4270         STATISTICS(jniinvokation());
4271
4272         ba = (java_booleanarray *) array;
4273
4274         if (elems != ba->data) {
4275                 switch (mode) {
4276                 case JNI_COMMIT:
4277                         MCOPY(ba->data, elems, u1, ba->header.size);
4278                         break;
4279                 case 0:
4280                         MCOPY(ba->data, elems, u1, ba->header.size);
4281                         /* XXX TWISTI how should it be freed? */
4282                         break;
4283                 case JNI_ABORT:
4284                         /* XXX TWISTI how should it be freed? */
4285                         break;
4286                 }
4287         }
4288 }
4289
4290
4291 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
4292                                                           jint mode)
4293 {
4294         java_bytearray *ba;
4295
4296         STATISTICS(jniinvokation());
4297
4298         ba = (java_bytearray *) array;
4299
4300         if (elems != ba->data) {
4301                 switch (mode) {
4302                 case JNI_COMMIT:
4303                         MCOPY(ba->data, elems, s1, ba->header.size);
4304                         break;
4305                 case 0:
4306                         MCOPY(ba->data, elems, s1, ba->header.size);
4307                         /* XXX TWISTI how should it be freed? */
4308                         break;
4309                 case JNI_ABORT:
4310                         /* XXX TWISTI how should it be freed? */
4311                         break;
4312                 }
4313         }
4314 }
4315
4316
4317 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
4318                                                           jint mode)
4319 {
4320         java_chararray *ca;
4321
4322         STATISTICS(jniinvokation());
4323
4324         ca = (java_chararray *) array;
4325
4326         if (elems != ca->data) {
4327                 switch (mode) {
4328                 case JNI_COMMIT:
4329                         MCOPY(ca->data, elems, u2, ca->header.size);
4330                         break;
4331                 case 0:
4332                         MCOPY(ca->data, elems, u2, ca->header.size);
4333                         /* XXX TWISTI how should it be freed? */
4334                         break;
4335                 case JNI_ABORT:
4336                         /* XXX TWISTI how should it be freed? */
4337                         break;
4338                 }
4339         }
4340 }
4341
4342
4343 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
4344                                                            jint mode)
4345 {
4346         java_shortarray *sa;
4347
4348         STATISTICS(jniinvokation());
4349
4350         sa = (java_shortarray *) array;
4351
4352         if (elems != sa->data) {
4353                 switch (mode) {
4354                 case JNI_COMMIT:
4355                         MCOPY(sa->data, elems, s2, sa->header.size);
4356                         break;
4357                 case 0:
4358                         MCOPY(sa->data, elems, s2, sa->header.size);
4359                         /* XXX TWISTI how should it be freed? */
4360                         break;
4361                 case JNI_ABORT:
4362                         /* XXX TWISTI how should it be freed? */
4363                         break;
4364                 }
4365         }
4366 }
4367
4368
4369 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4370                                                          jint mode)
4371 {
4372         java_intarray *ia;
4373
4374         STATISTICS(jniinvokation());
4375
4376         ia = (java_intarray *) array;
4377
4378         if (elems != ia->data) {
4379                 switch (mode) {
4380                 case JNI_COMMIT:
4381                         MCOPY(ia->data, elems, s4, ia->header.size);
4382                         break;
4383                 case 0:
4384                         MCOPY(ia->data, elems, s4, ia->header.size);
4385                         /* XXX TWISTI how should it be freed? */
4386                         break;
4387                 case JNI_ABORT:
4388                         /* XXX TWISTI how should it be freed? */
4389                         break;
4390                 }
4391         }
4392 }
4393
4394
4395 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
4396                                                           jint mode)
4397 {
4398         java_longarray *la;
4399
4400         STATISTICS(jniinvokation());
4401
4402         la = (java_longarray *) array;
4403
4404         /* We cast this one to prevent a compiler warning on 64-bit
4405            systems since GNU Classpath typedef jlong to long long. */
4406
4407         if ((s8 *) elems != la->data) {
4408                 switch (mode) {
4409                 case JNI_COMMIT:
4410                         MCOPY(la->data, elems, s8, la->header.size);
4411                         break;
4412                 case 0:
4413                         MCOPY(la->data, elems, s8, la->header.size);
4414                         /* XXX TWISTI how should it be freed? */
4415                         break;
4416                 case JNI_ABORT:
4417                         /* XXX TWISTI how should it be freed? */
4418                         break;
4419                 }
4420         }
4421 }
4422
4423
4424 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
4425                                                            jint mode)
4426 {
4427         java_floatarray *fa;
4428
4429         STATISTICS(jniinvokation());
4430
4431         fa = (java_floatarray *) array;
4432
4433         if (elems != fa->data) {
4434                 switch (mode) {
4435                 case JNI_COMMIT:
4436                         MCOPY(fa->data, elems, float, fa->header.size);
4437                         break;
4438                 case 0:
4439                         MCOPY(fa->data, elems, float, fa->header.size);
4440                         /* XXX TWISTI how should it be freed? */
4441                         break;
4442                 case JNI_ABORT:
4443                         /* XXX TWISTI how should it be freed? */
4444                         break;
4445                 }
4446         }
4447 }
4448
4449
4450 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4451                                                                 jdouble *elems, jint mode)
4452 {
4453         java_doublearray *da;
4454
4455         STATISTICS(jniinvokation());
4456
4457         da = (java_doublearray *) array;
4458
4459         if (elems != da->data) {
4460                 switch (mode) {
4461                 case JNI_COMMIT:
4462                         MCOPY(da->data, elems, double, da->header.size);
4463                         break;
4464                 case 0:
4465                         MCOPY(da->data, elems, double, da->header.size);
4466                         /* XXX TWISTI how should it be freed? */
4467                         break;
4468                 case JNI_ABORT:
4469                         /* XXX TWISTI how should it be freed? */
4470                         break;
4471                 }
4472         }
4473 }
4474
4475
4476 /*  Get<PrimitiveType>ArrayRegion **********************************************
4477
4478         A family of functions that copies a region of a primitive array
4479         into a buffer.
4480
4481 *******************************************************************************/
4482
4483 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4484                                                    jsize len, jboolean *buf)
4485 {
4486         java_booleanarray *ba;
4487
4488         STATISTICS(jniinvokation());
4489
4490         ba = (java_booleanarray *) array;
4491
4492     if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4493                 exceptions_throw_arrayindexoutofboundsexception();
4494     else
4495                 MCOPY(buf, &ba->data[start], u1, len);
4496 }
4497
4498
4499 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4500                                                 jbyte *buf)
4501 {
4502         java_bytearray *ba;
4503
4504         STATISTICS(jniinvokation());
4505
4506         ba = (java_bytearray *) array;
4507
4508         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4509                 exceptions_throw_arrayindexoutofboundsexception();
4510         else
4511                 MCOPY(buf, &ba->data[start], s1, len);
4512 }
4513
4514
4515 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4516                                                 jchar *buf)
4517 {
4518         java_chararray *ca;
4519
4520         STATISTICS(jniinvokation());
4521
4522         ca = (java_chararray *) array;
4523
4524         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4525                 exceptions_throw_arrayindexoutofboundsexception();
4526         else
4527                 MCOPY(buf, &ca->data[start], u2, len);
4528 }
4529
4530
4531 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4532                                                  jsize len, jshort *buf)
4533 {
4534         java_shortarray *sa;
4535
4536         STATISTICS(jniinvokation());
4537
4538         sa = (java_shortarray *) array;
4539
4540         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4541                 exceptions_throw_arrayindexoutofboundsexception();
4542         else    
4543                 MCOPY(buf, &sa->data[start], s2, len);
4544 }
4545
4546
4547 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4548                                            jint *buf)
4549 {
4550         java_intarray *ia;
4551
4552         STATISTICS(jniinvokation());
4553
4554         ia = (java_intarray *) array;
4555
4556         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4557                 exceptions_throw_arrayindexoutofboundsexception();
4558         else
4559                 MCOPY(buf, &ia->data[start], s4, len);
4560 }
4561
4562
4563 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
4564                                                 jlong *buf)
4565 {
4566         java_longarray *la;
4567
4568         STATISTICS(jniinvokation());
4569
4570         la = (java_longarray *) array;
4571
4572         if ((start < 0) || (len < 0) || (start + len > la->header.size))
4573                 exceptions_throw_arrayindexoutofboundsexception();
4574         else
4575                 MCOPY(buf, &la->data[start], s8, len);
4576 }
4577
4578
4579 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4580                                                  jsize len, jfloat *buf)
4581 {
4582         java_floatarray *fa;
4583
4584         STATISTICS(jniinvokation());
4585
4586         fa = (java_floatarray *) array;
4587
4588         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4589                 exceptions_throw_arrayindexoutofboundsexception();
4590         else
4591                 MCOPY(buf, &fa->data[start], float, len);
4592 }
4593
4594
4595 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4596                                                   jsize len, jdouble *buf)
4597 {
4598         java_doublearray *da;
4599
4600         STATISTICS(jniinvokation());
4601
4602         da = (java_doublearray *) array;
4603
4604         if ((start < 0) || (len < 0) || (start + len > da->header.size))
4605                 exceptions_throw_arrayindexoutofboundsexception();
4606         else
4607                 MCOPY(buf, &da->data[start], double, len);
4608 }
4609
4610
4611 /*  Set<PrimitiveType>ArrayRegion **********************************************
4612
4613         A family of functions that copies back a region of a primitive
4614         array from a buffer.
4615
4616 *******************************************************************************/
4617
4618 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
4619                                                    jsize len, jboolean *buf)
4620 {
4621         java_booleanarray *ba;
4622
4623         STATISTICS(jniinvokation());
4624
4625         ba = (java_booleanarray *) array;
4626
4627         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4628                 exceptions_throw_arrayindexoutofboundsexception();
4629         else
4630                 MCOPY(&ba->data[start], buf, u1, len);
4631 }
4632
4633
4634 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
4635                                                 jbyte *buf)
4636 {
4637         java_bytearray *ba;
4638
4639         STATISTICS(jniinvokation());
4640
4641         ba = (java_bytearray *) array;
4642
4643         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4644                 exceptions_throw_arrayindexoutofboundsexception();
4645         else
4646                 MCOPY(&ba->data[start], buf, s1, len);
4647 }
4648
4649
4650 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
4651                                                 jchar *buf)
4652 {
4653         java_chararray *ca;
4654
4655         STATISTICS(jniinvokation());
4656
4657         ca = (java_chararray *) array;
4658
4659         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4660                 exceptions_throw_arrayindexoutofboundsexception();
4661         else
4662                 MCOPY(&ca->data[start], buf, u2, len);
4663 }
4664
4665
4666 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4667                                                  jsize len, jshort *buf)
4668 {
4669         java_shortarray *sa;
4670
4671         STATISTICS(jniinvokation());
4672
4673         sa = (java_shortarray *) array;
4674
4675         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4676                 exceptions_throw_arrayindexoutofboundsexception();
4677         else
4678                 MCOPY(&sa->data[start], buf, s2, len);
4679 }
4680
4681
4682 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
4683                                            jint *buf)
4684 {
4685         java_intarray *ia;
4686
4687         STATISTICS(jniinvokation());
4688
4689         ia = (java_intarray *) array;
4690
4691         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4692                 exceptions_throw_arrayindexoutofboundsexception();
4693         else
4694                 MCOPY(&ia->data[start], buf, s4, len);
4695 }
4696
4697
4698 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
4699                                                 jlong *buf)
4700 {
4701         java_longarray *la;
4702
4703         STATISTICS(jniinvokation());
4704
4705         la = (java_longarray *) array;
4706
4707         if ((start < 0) || (len < 0) || (start + len > la->header.size))
4708                 exceptions_throw_arrayindexoutofboundsexception();
4709         else
4710                 MCOPY(&la->data[start], buf, s8, len);
4711 }
4712
4713
4714 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4715                                                  jsize len, jfloat *buf)
4716 {
4717         java_floatarray *fa;
4718
4719         STATISTICS(jniinvokation());
4720
4721         fa = (java_floatarray *) array;
4722
4723         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4724                 exceptions_throw_arrayindexoutofboundsexception();
4725         else
4726                 MCOPY(&fa->data[start], buf, float, len);
4727 }
4728
4729
4730 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4731                                                   jsize len, jdouble *buf)
4732 {
4733         java_doublearray *da;
4734
4735         STATISTICS(jniinvokation());
4736
4737         da = (java_doublearray *) array;
4738
4739         if ((start < 0) || (len < 0) || (start + len > da->header.size))
4740                 exceptions_throw_arrayindexoutofboundsexception();
4741         else
4742                 MCOPY(&da->data[start], buf, double, len);
4743 }
4744
4745
4746 /* Registering Native Methods *************************************************/
4747
4748 /* RegisterNatives *************************************************************
4749
4750    Registers native methods with the class specified by the clazz
4751    argument. The methods parameter specifies an array of
4752    JNINativeMethod structures that contain the names, signatures, and
4753    function pointers of the native methods. The nMethods parameter
4754    specifies the number of native methods in the array.
4755
4756 *******************************************************************************/
4757
4758 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4759                                          jint nMethods)
4760 {
4761         STATISTICS(jniinvokation());
4762
4763     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4764
4765     return 0;
4766 }
4767
4768
4769 /* UnregisterNatives ***********************************************************
4770
4771    Unregisters native methods of a class. The class goes back to the
4772    state before it was linked or registered with its native method
4773    functions.
4774
4775    This function should not be used in normal native code. Instead, it
4776    provides special programs a way to reload and relink native
4777    libraries.
4778
4779 *******************************************************************************/
4780
4781 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4782 {
4783         STATISTICS(jniinvokation());
4784
4785         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4786
4787     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4788
4789     return 0;
4790 }
4791
4792
4793 /* Monitor Operations *********************************************************/
4794
4795 /* MonitorEnter ****************************************************************
4796
4797    Enters the monitor associated with the underlying Java object
4798    referred to by obj.
4799
4800 *******************************************************************************/
4801
4802 jint MonitorEnter(JNIEnv *env, jobject obj)
4803 {
4804         STATISTICS(jniinvokation());
4805
4806         if (!obj) {
4807                 exceptions_throw_nullpointerexception();
4808                 return JNI_ERR;
4809         }
4810
4811 #if defined(USE_THREADS)
4812         builtin_monitorenter(obj);
4813 #endif
4814
4815         return JNI_OK;
4816 }
4817
4818
4819 /* MonitorExit *****************************************************************
4820
4821    The current thread must be the owner of the monitor associated with
4822    the underlying Java object referred to by obj. The thread
4823    decrements the counter indicating the number of times it has
4824    entered this monitor. If the value of the counter becomes zero, the
4825    current thread releases the monitor.
4826
4827 *******************************************************************************/
4828
4829 jint MonitorExit(JNIEnv *env, jobject obj)
4830 {
4831         STATISTICS(jniinvokation());
4832
4833         if (!obj) {
4834                 exceptions_throw_nullpointerexception();
4835                 return JNI_ERR;
4836         }
4837
4838 #if defined(USE_THREADS)
4839         builtin_monitorexit(obj);
4840 #endif
4841
4842         return JNI_OK;
4843 }
4844
4845
4846 /* JavaVM Interface ***********************************************************/
4847
4848 /* GetJavaVM *******************************************************************
4849
4850    Returns the Java VM interface (used in the Invocation API)
4851    associated with the current thread. The result is placed at the
4852    location pointed to by the second argument, vm.
4853
4854 *******************************************************************************/
4855
4856 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4857 {
4858         STATISTICS(jniinvokation());
4859
4860     *vm = (JavaVM *) _Jv_jvm;
4861
4862         return 0;
4863 }
4864
4865
4866 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4867 {
4868         STATISTICS(jniinvokation());
4869
4870         log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4871 }
4872
4873
4874 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4875 {
4876         STATISTICS(jniinvokation());
4877
4878         log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4879 }
4880
4881
4882 /* GetPrimitiveArrayCritical ***************************************************
4883
4884    Obtain a direct pointer to array elements.
4885
4886 *******************************************************************************/
4887
4888 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4889 {
4890         java_bytearray *ba;
4891         jbyte          *bp;
4892
4893         ba = (java_bytearray *) array;
4894
4895         /* do the same as Kaffe does */
4896
4897         bp = GetByteArrayElements(env, ba, isCopy);
4898
4899         return (void *) bp;
4900 }
4901
4902
4903 /* ReleasePrimitiveArrayCritical ***********************************************
4904
4905    No specific documentation.
4906
4907 *******************************************************************************/
4908
4909 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4910                                                                    jint mode)
4911 {
4912         STATISTICS(jniinvokation());
4913
4914         /* do the same as Kaffe does */
4915
4916         ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4917 }
4918
4919
4920 /* GetStringCritical ***********************************************************
4921
4922    The semantics of these two functions are similar to the existing
4923    Get/ReleaseStringChars functions.
4924
4925 *******************************************************************************/
4926
4927 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4928 {
4929         STATISTICS(jniinvokation());
4930
4931         return GetStringChars(env, string, isCopy);
4932 }
4933
4934
4935 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4936 {
4937         STATISTICS(jniinvokation());
4938
4939         ReleaseStringChars(env, string, cstring);
4940 }
4941
4942
4943 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4944 {
4945         STATISTICS(jniinvokation());
4946
4947         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4948
4949         return obj;
4950 }
4951
4952
4953 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4954 {
4955         STATISTICS(jniinvokation());
4956
4957         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4958 }
4959
4960
4961 /* NewGlobalRef ****************************************************************
4962
4963    Creates a new global reference to the object referred to by the obj
4964    argument.
4965
4966 *******************************************************************************/
4967     
4968 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4969 {
4970         java_objectheader *o;
4971         java_lang_Integer *refcount;
4972         java_objectheader *newval;
4973
4974         STATISTICS(jniinvokation());
4975
4976 #if defined(USE_THREADS)
4977         builtin_monitorenter(*global_ref_table);
4978 #endif
4979         
4980         o = vm_call_method(getmid, *global_ref_table, lobj);
4981
4982         refcount = (java_lang_Integer *) o;
4983
4984         if (refcount == NULL) {
4985                 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4986
4987                 if (newval == NULL) {
4988 #if defined(USE_THREADS)
4989                         builtin_monitorexit(*global_ref_table);
4990 #endif
4991                         return NULL;
4992                 }
4993
4994                 (void) vm_call_method(putmid, *global_ref_table, lobj, newval);
4995
4996         } else {
4997                 /* we can access the object itself, as we are in a
4998            synchronized section */
4999
5000                 refcount->value++;
5001         }
5002
5003 #if defined(USE_THREADS)
5004         builtin_monitorexit(*global_ref_table);
5005 #endif
5006
5007         return lobj;
5008 }
5009
5010
5011 /* DeleteGlobalRef *************************************************************
5012
5013    Deletes the global reference pointed to by globalRef.
5014
5015 *******************************************************************************/
5016
5017 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5018 {
5019         java_objectheader *o;
5020         java_lang_Integer *refcount;
5021         s4                 val;
5022
5023         STATISTICS(jniinvokation());
5024
5025 #if defined(USE_THREADS)
5026         builtin_monitorenter(*global_ref_table);
5027 #endif
5028
5029         o = vm_call_method(getmid, *global_ref_table, globalRef);
5030
5031         refcount = (java_lang_Integer *) o;
5032
5033         if (refcount == NULL) {
5034                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
5035                 return;
5036         }
5037
5038         /* we can access the object itself, as we are in a synchronized
5039            section */
5040
5041         val = refcount->value - 1;
5042
5043         if (val == 0) {
5044                 (void) vm_call_method(removemid, *global_ref_table, refcount);
5045
5046         } else {
5047                 /* we do not create a new object, but set the new value into
5048            the old one */
5049
5050                 refcount->value = val;
5051         }
5052
5053 #if defined(USE_THREADS)
5054         builtin_monitorexit(*global_ref_table);
5055 #endif
5056 }
5057
5058
5059 /* ExceptionCheck **************************************************************
5060
5061    Returns JNI_TRUE when there is a pending exception; otherwise,
5062    returns JNI_FALSE.
5063
5064 *******************************************************************************/
5065
5066 jboolean ExceptionCheck(JNIEnv *env)
5067 {
5068         STATISTICS(jniinvokation());
5069
5070         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
5071 }
5072
5073
5074 /* New JNI 1.4 functions ******************************************************/
5075
5076 /* NewDirectByteBuffer *********************************************************
5077
5078    Allocates and returns a direct java.nio.ByteBuffer referring to the
5079    block of memory starting at the memory address address and
5080    extending capacity bytes.
5081
5082 *******************************************************************************/
5083
5084 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5085 {
5086         java_objectheader       *nbuf;
5087 #if SIZEOF_VOID_P == 8
5088         gnu_classpath_Pointer64 *paddress;
5089 #else
5090         gnu_classpath_Pointer32 *paddress;
5091 #endif
5092
5093         STATISTICS(jniinvokation());
5094
5095         /* alocate a gnu.classpath.Pointer{32,64} object */
5096
5097 #if SIZEOF_VOID_P == 8
5098         if (!(paddress = (gnu_classpath_Pointer64 *)
5099                   builtin_new(class_gnu_classpath_Pointer64)))
5100 #else
5101         if (!(paddress = (gnu_classpath_Pointer32 *)
5102                   builtin_new(class_gnu_classpath_Pointer32)))
5103 #endif
5104                 return NULL;
5105
5106         /* fill gnu.classpath.Pointer{32,64} with address */
5107
5108         paddress->data = (ptrint) address;
5109
5110         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5111
5112         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5113                                                          (jmethodID) dbbirw_init, NULL, paddress,
5114                                                          (jint) capacity, (jint) capacity, (jint) 0);
5115
5116         /* add local reference and return the value */
5117
5118         return NewLocalRef(env, nbuf);
5119 }
5120
5121
5122 /* GetDirectBufferAddress ******************************************************
5123
5124    Fetches and returns the starting address of the memory region
5125    referenced by the given direct java.nio.Buffer.
5126
5127 *******************************************************************************/
5128
5129 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
5130 {
5131         java_nio_DirectByteBufferImpl *nbuf;
5132 #if SIZEOF_VOID_P == 8
5133         gnu_classpath_Pointer64       *address;
5134 #else
5135         gnu_classpath_Pointer32       *address;
5136 #endif
5137
5138         STATISTICS(jniinvokation());
5139
5140         if (!builtin_instanceof(buf, class_java_nio_Buffer))
5141                 return NULL;
5142
5143         nbuf = (java_nio_DirectByteBufferImpl *) buf;
5144
5145 #if SIZEOF_VOID_P == 8
5146         address = (gnu_classpath_Pointer64 *) nbuf->address;
5147 #else
5148         address = (gnu_classpath_Pointer32 *) nbuf->address;
5149 #endif
5150
5151         return (void *) address->data;
5152 }
5153
5154
5155 /* GetDirectBufferCapacity *****************************************************
5156
5157    Fetches and returns the capacity in bytes of the memory region
5158    referenced by the given direct java.nio.Buffer.
5159
5160 *******************************************************************************/
5161
5162 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5163 {
5164         java_nio_Buffer *nbuf;
5165
5166         STATISTICS(jniinvokation());
5167
5168         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5169                 return -1;
5170
5171         nbuf = (java_nio_Buffer *) buf;
5172
5173         return (jlong) nbuf->cap;
5174 }
5175
5176
5177 /* DestroyJavaVM ***************************************************************
5178
5179    Unloads a Java VM and reclaims its resources. Only the main thread
5180    can unload the VM. The system waits until the main thread is only
5181    remaining user thread before it destroys the VM.
5182
5183 *******************************************************************************/
5184
5185 jint DestroyJavaVM(JavaVM *vm)
5186 {
5187         s4 status;
5188
5189         STATISTICS(jniinvokation());
5190
5191     status = vm_destroy(vm);
5192
5193         return status;
5194 }
5195
5196
5197 /* AttachCurrentThread *********************************************************
5198
5199    Attaches the current thread to a Java VM. Returns a JNI interface
5200    pointer in the JNIEnv argument.
5201
5202    Trying to attach a thread that is already attached is a no-op.
5203
5204    A native thread cannot be attached simultaneously to two Java VMs.
5205
5206    When a thread is attached to the VM, the context class loader is
5207    the bootstrap loader.
5208
5209 *******************************************************************************/
5210
5211 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
5212 {
5213         STATISTICS(jniinvokation());
5214
5215         log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
5216
5217 #if !defined(HAVE___THREAD)
5218 /*      cacao_thread_attach();*/
5219 #else
5220         #error "No idea how to implement that. Perhaps Stefan knows"
5221 #endif
5222
5223         *env = _Jv_env;
5224
5225         return 0;
5226 }
5227
5228
5229 jint DetachCurrentThread(JavaVM *vm)
5230 {
5231         STATISTICS(jniinvokation());
5232
5233         log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
5234
5235         return 0;
5236 }
5237
5238
5239 /* GetEnv **********************************************************************
5240
5241    If the current thread is not attached to the VM, sets *env to NULL,
5242    and returns JNI_EDETACHED. If the specified version is not
5243    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5244    sets *env to the appropriate interface, and returns JNI_OK.
5245
5246 *******************************************************************************/
5247
5248 jint GetEnv(JavaVM *vm, void **env, jint version)
5249 {
5250         STATISTICS(jniinvokation());
5251
5252 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5253         if (thread_getself() == NULL) {
5254                 *env = NULL;
5255
5256                 return JNI_EDETACHED;
5257         }
5258 #endif
5259
5260         if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
5261                 (version == JNI_VERSION_1_4)) {
5262                 *env = _Jv_env;
5263
5264                 return JNI_OK;
5265         }
5266
5267 #if defined(ENABLE_JVMTI)
5268         if (version == JVMTI_VERSION_1_0) {
5269                 *env = (void *) new_jvmtienv();
5270
5271                 if (env != NULL)
5272                         return JNI_OK;
5273         }
5274 #endif
5275         
5276         *env = NULL;
5277
5278         return JNI_EVERSION;
5279 }
5280
5281
5282
5283 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
5284 {
5285         STATISTICS(jniinvokation());
5286
5287         log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
5288
5289         return 0;
5290 }
5291
5292
5293 /* JNI invocation table *******************************************************/
5294
5295 const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
5296         NULL,
5297         NULL,
5298         NULL,
5299
5300         DestroyJavaVM,
5301         AttachCurrentThread,
5302         DetachCurrentThread,
5303         GetEnv,
5304         AttachCurrentThreadAsDaemon
5305 };
5306
5307
5308 /* JNI function table *********************************************************/
5309
5310 struct JNINativeInterface _Jv_JNINativeInterface = {
5311         NULL,
5312         NULL,
5313         NULL,
5314         NULL,    
5315         GetVersion,
5316
5317         DefineClass,
5318         FindClass,
5319         FromReflectedMethod,
5320         FromReflectedField,
5321         ToReflectedMethod,
5322         GetSuperclass,
5323         IsAssignableFrom,
5324         ToReflectedField,
5325
5326         Throw,
5327         ThrowNew,
5328         ExceptionOccurred,
5329         ExceptionDescribe,
5330         ExceptionClear,
5331         FatalError,
5332         PushLocalFrame,
5333         PopLocalFrame,
5334
5335         NewGlobalRef,
5336         DeleteGlobalRef,
5337         DeleteLocalRef,
5338         IsSameObject,
5339         NewLocalRef,
5340         EnsureLocalCapacity,
5341
5342         AllocObject,
5343         NewObject,
5344         NewObjectV,
5345         NewObjectA,
5346
5347         GetObjectClass,
5348         IsInstanceOf,
5349
5350         GetMethodID,
5351
5352         CallObjectMethod,
5353         CallObjectMethodV,
5354         CallObjectMethodA,
5355         CallBooleanMethod,
5356         CallBooleanMethodV,
5357         CallBooleanMethodA,
5358         CallByteMethod,
5359         CallByteMethodV,
5360         CallByteMethodA,
5361         CallCharMethod,
5362         CallCharMethodV,
5363         CallCharMethodA,
5364         CallShortMethod,
5365         CallShortMethodV,
5366         CallShortMethodA,
5367         CallIntMethod,
5368         CallIntMethodV,
5369         CallIntMethodA,
5370         CallLongMethod,
5371         CallLongMethodV,
5372         CallLongMethodA,
5373         CallFloatMethod,
5374         CallFloatMethodV,
5375         CallFloatMethodA,
5376         CallDoubleMethod,
5377         CallDoubleMethodV,
5378         CallDoubleMethodA,
5379         CallVoidMethod,
5380         CallVoidMethodV,
5381         CallVoidMethodA,
5382
5383         CallNonvirtualObjectMethod,
5384         CallNonvirtualObjectMethodV,
5385         CallNonvirtualObjectMethodA,
5386         CallNonvirtualBooleanMethod,
5387         CallNonvirtualBooleanMethodV,
5388         CallNonvirtualBooleanMethodA,
5389         CallNonvirtualByteMethod,
5390         CallNonvirtualByteMethodV,
5391         CallNonvirtualByteMethodA,
5392         CallNonvirtualCharMethod,
5393         CallNonvirtualCharMethodV,
5394         CallNonvirtualCharMethodA,
5395         CallNonvirtualShortMethod,
5396         CallNonvirtualShortMethodV,
5397         CallNonvirtualShortMethodA,
5398         CallNonvirtualIntMethod,
5399         CallNonvirtualIntMethodV,
5400         CallNonvirtualIntMethodA,
5401         CallNonvirtualLongMethod,
5402         CallNonvirtualLongMethodV,
5403         CallNonvirtualLongMethodA,
5404         CallNonvirtualFloatMethod,
5405         CallNonvirtualFloatMethodV,
5406         CallNonvirtualFloatMethodA,
5407         CallNonvirtualDoubleMethod,
5408         CallNonvirtualDoubleMethodV,
5409         CallNonvirtualDoubleMethodA,
5410         CallNonvirtualVoidMethod,
5411         CallNonvirtualVoidMethodV,
5412         CallNonvirtualVoidMethodA,
5413
5414         GetFieldID,
5415
5416         GetObjectField,
5417         GetBooleanField,
5418         GetByteField,
5419         GetCharField,
5420         GetShortField,
5421         GetIntField,
5422         GetLongField,
5423         GetFloatField,
5424         GetDoubleField,
5425         SetObjectField,
5426         SetBooleanField,
5427         SetByteField,
5428         SetCharField,
5429         SetShortField,
5430         SetIntField,
5431         SetLongField,
5432         SetFloatField,
5433         SetDoubleField,
5434
5435         GetStaticMethodID,
5436
5437         CallStaticObjectMethod,
5438         CallStaticObjectMethodV,
5439         CallStaticObjectMethodA,
5440         CallStaticBooleanMethod,
5441         CallStaticBooleanMethodV,
5442         CallStaticBooleanMethodA,
5443         CallStaticByteMethod,
5444         CallStaticByteMethodV,
5445         CallStaticByteMethodA,
5446         CallStaticCharMethod,
5447         CallStaticCharMethodV,
5448         CallStaticCharMethodA,
5449         CallStaticShortMethod,
5450         CallStaticShortMethodV,
5451         CallStaticShortMethodA,
5452         CallStaticIntMethod,
5453         CallStaticIntMethodV,
5454         CallStaticIntMethodA,
5455         CallStaticLongMethod,
5456         CallStaticLongMethodV,
5457         CallStaticLongMethodA,
5458         CallStaticFloatMethod,
5459         CallStaticFloatMethodV,
5460         CallStaticFloatMethodA,
5461         CallStaticDoubleMethod,
5462         CallStaticDoubleMethodV,
5463         CallStaticDoubleMethodA,
5464         CallStaticVoidMethod,
5465         CallStaticVoidMethodV,
5466         CallStaticVoidMethodA,
5467
5468         GetStaticFieldID,
5469
5470         GetStaticObjectField,
5471         GetStaticBooleanField,
5472         GetStaticByteField,
5473         GetStaticCharField,
5474         GetStaticShortField,
5475         GetStaticIntField,
5476         GetStaticLongField,
5477         GetStaticFloatField,
5478         GetStaticDoubleField,
5479         SetStaticObjectField,
5480         SetStaticBooleanField,
5481         SetStaticByteField,
5482         SetStaticCharField,
5483         SetStaticShortField,
5484         SetStaticIntField,
5485         SetStaticLongField,
5486         SetStaticFloatField,
5487         SetStaticDoubleField,
5488
5489         NewString,
5490         GetStringLength,
5491         GetStringChars,
5492         ReleaseStringChars,
5493
5494         NewStringUTF,
5495         GetStringUTFLength,
5496         GetStringUTFChars,
5497         ReleaseStringUTFChars,
5498
5499         GetArrayLength,
5500
5501         NewObjectArray,
5502         GetObjectArrayElement,
5503         SetObjectArrayElement,
5504
5505         NewBooleanArray,
5506         NewByteArray,
5507         NewCharArray,
5508         NewShortArray,
5509         NewIntArray,
5510         NewLongArray,
5511         NewFloatArray,
5512         NewDoubleArray,
5513
5514         GetBooleanArrayElements,
5515         GetByteArrayElements,
5516         GetCharArrayElements,
5517         GetShortArrayElements,
5518         GetIntArrayElements,
5519         GetLongArrayElements,
5520         GetFloatArrayElements,
5521         GetDoubleArrayElements,
5522
5523         ReleaseBooleanArrayElements,
5524         ReleaseByteArrayElements,
5525         ReleaseCharArrayElements,
5526         ReleaseShortArrayElements,
5527         ReleaseIntArrayElements,
5528         ReleaseLongArrayElements,
5529         ReleaseFloatArrayElements,
5530         ReleaseDoubleArrayElements,
5531
5532         GetBooleanArrayRegion,
5533         GetByteArrayRegion,
5534         GetCharArrayRegion,
5535         GetShortArrayRegion,
5536         GetIntArrayRegion,
5537         GetLongArrayRegion,
5538         GetFloatArrayRegion,
5539         GetDoubleArrayRegion,
5540         SetBooleanArrayRegion,
5541         SetByteArrayRegion,
5542         SetCharArrayRegion,
5543         SetShortArrayRegion,
5544         SetIntArrayRegion,
5545         SetLongArrayRegion,
5546         SetFloatArrayRegion,
5547         SetDoubleArrayRegion,
5548
5549         RegisterNatives,
5550         UnregisterNatives,
5551
5552         MonitorEnter,
5553         MonitorExit,
5554
5555         GetJavaVM,
5556
5557         /* new JNI 1.2 functions */
5558
5559         GetStringRegion,
5560         GetStringUTFRegion,
5561
5562         GetPrimitiveArrayCritical,
5563         ReleasePrimitiveArrayCritical,
5564
5565         GetStringCritical,
5566         ReleaseStringCritical,
5567
5568         NewWeakGlobalRef,
5569         DeleteWeakGlobalRef,
5570
5571         ExceptionCheck,
5572
5573         /* new JNI 1.4 functions */
5574
5575         NewDirectByteBuffer,
5576         GetDirectBufferAddress,
5577         GetDirectBufferCapacity
5578 };
5579
5580
5581 /* Invocation API Functions ***************************************************/
5582
5583 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5584
5585    Returns a default configuration for the Java VM.
5586
5587 *******************************************************************************/
5588
5589 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5590 {
5591         JavaVMInitArgs *_vm_args;
5592
5593         _vm_args = (JavaVMInitArgs *) vm_args;
5594
5595         /* GNU classpath currently supports JNI 1.2 */
5596
5597         switch (_vm_args->version) {
5598     case JNI_VERSION_1_1:
5599                 _vm_args->version = JNI_VERSION_1_1;
5600                 break;
5601
5602     case JNI_VERSION_1_2:
5603     case JNI_VERSION_1_4:
5604                 _vm_args->ignoreUnrecognized = JNI_FALSE;
5605                 _vm_args->options = NULL;
5606                 _vm_args->nOptions = 0;
5607                 break;
5608
5609     default:
5610                 return -1;
5611         }
5612   
5613         return 0;
5614 }
5615
5616
5617 /* JNI_GetCreatedJavaVMs *******************************************************
5618
5619    Returns all Java VMs that have been created. Pointers to VMs are written in
5620    the buffer vmBuf in the order they are created. At most bufLen number of
5621    entries will be written. The total number of created VMs is returned in
5622    *nVMs.
5623
5624 *******************************************************************************/
5625
5626 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5627 {
5628         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5629
5630         return 0;
5631 }
5632
5633
5634 /* JNI_CreateJavaVM ************************************************************
5635
5636    Loads and initializes a Java VM. The current thread becomes the main thread.
5637    Sets the env argument to the JNI interface pointer of the main thread.
5638
5639 *******************************************************************************/
5640
5641 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
5642 {
5643         JavaVMInitArgs *_vm_args;
5644         _Jv_JNIEnv     *env;
5645         _Jv_JavaVM     *jvm;
5646         localref_table *lrt;
5647
5648         /* get the arguments for the new JVM */
5649
5650         _vm_args = (JavaVMInitArgs *) vm_args;
5651
5652         /* get the VM and Env tables (must be set before vm_create) */
5653
5654         env = NEW(_Jv_JNIEnv);
5655         env->env = &_Jv_JNINativeInterface;
5656
5657         /* XXX Set the global variable.  Maybe we should do that differently. */
5658
5659         _Jv_env = env;
5660
5661         /* actually create the JVM */
5662
5663         if (!vm_create(_vm_args))
5664                 return -1;
5665
5666         /* create and fill a JavaVM structure */
5667
5668         jvm = NEW(_Jv_JavaVM);
5669         jvm->functions = &_Jv_JNIInvokeInterface;
5670
5671         /* XXX Set the global variable.  Maybe we should do that differently. */
5672
5673         _Jv_jvm = jvm;
5674
5675         /* setup the local ref table (must be created after vm_create) */
5676
5677         lrt = GCNEW(localref_table);
5678
5679         lrt->capacity    = LOCALREFTABLE_CAPACITY;
5680         lrt->used        = 0;
5681         lrt->localframes = 1;
5682         lrt->prev        = LOCALREFTABLE;
5683
5684         /* clear the references array (memset is faster then a for-loop) */
5685
5686         MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
5687
5688         LOCALREFTABLE = lrt;
5689
5690         /* now return the values */
5691
5692         *p_vm  = (JavaVM *) jvm;
5693         *p_env = (void *) env;
5694
5695         return 0;
5696 }
5697
5698
5699 /*
5700  * These are local overrides for various environment variables in Emacs.
5701  * Please do not remove this and leave it at the end of the file, where
5702  * Emacs will automagically detect them.
5703  * ---------------------------------------------------------------------
5704  * Local variables:
5705  * mode: c
5706  * indent-tabs-mode: t
5707  * c-basic-offset: 4
5708  * tab-width: 4
5709  * End:
5710  * vim:noexpandtab:sw=4:ts=4:
5711  */