* src/vm/string.c (string_java_lang_StringIndexOutOfBoundsException): Added.
[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 4566 2006-03-07 10:36:42Z 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 /* GetStringRegion *************************************************************
4867
4868    Copies len number of Unicode characters beginning at offset start
4869    to the given buffer buf.
4870
4871    Throws StringIndexOutOfBoundsException on index overflow.
4872
4873 *******************************************************************************/
4874
4875 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4876 {
4877         java_lang_String *s;
4878         java_chararray   *ca;
4879
4880         STATISTICS(jniinvokation());
4881
4882         s  = (java_lang_String *) str;
4883         ca = s->value;
4884
4885         if ((start < 0) || (len < 0) || (start > s->count) ||
4886                 (start + len > s->count)) {
4887                 exceptions_throw_stringindexoutofboundsexception();
4888                 return;
4889         }
4890
4891         MCOPY(buf, &ca->data[start], u2, len);
4892 }
4893
4894
4895 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4896 {
4897         STATISTICS(jniinvokation());
4898
4899         log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4900 }
4901
4902
4903 /* GetPrimitiveArrayCritical ***************************************************
4904
4905    Obtain a direct pointer to array elements.
4906
4907 *******************************************************************************/
4908
4909 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4910 {
4911         java_bytearray *ba;
4912         jbyte          *bp;
4913
4914         ba = (java_bytearray *) array;
4915
4916         /* do the same as Kaffe does */
4917
4918         bp = GetByteArrayElements(env, ba, isCopy);
4919
4920         return (void *) bp;
4921 }
4922
4923
4924 /* ReleasePrimitiveArrayCritical ***********************************************
4925
4926    No specific documentation.
4927
4928 *******************************************************************************/
4929
4930 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4931                                                                    jint mode)
4932 {
4933         STATISTICS(jniinvokation());
4934
4935         /* do the same as Kaffe does */
4936
4937         ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4938 }
4939
4940
4941 /* GetStringCritical ***********************************************************
4942
4943    The semantics of these two functions are similar to the existing
4944    Get/ReleaseStringChars functions.
4945
4946 *******************************************************************************/
4947
4948 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4949 {
4950         STATISTICS(jniinvokation());
4951
4952         return GetStringChars(env, string, isCopy);
4953 }
4954
4955
4956 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4957 {
4958         STATISTICS(jniinvokation());
4959
4960         ReleaseStringChars(env, string, cstring);
4961 }
4962
4963
4964 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4965 {
4966         STATISTICS(jniinvokation());
4967
4968         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4969
4970         return obj;
4971 }
4972
4973
4974 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4975 {
4976         STATISTICS(jniinvokation());
4977
4978         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4979 }
4980
4981
4982 /* NewGlobalRef ****************************************************************
4983
4984    Creates a new global reference to the object referred to by the obj
4985    argument.
4986
4987 *******************************************************************************/
4988     
4989 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4990 {
4991         java_objectheader *o;
4992         java_lang_Integer *refcount;
4993         java_objectheader *newval;
4994
4995         STATISTICS(jniinvokation());
4996
4997 #if defined(USE_THREADS)
4998         builtin_monitorenter(*global_ref_table);
4999 #endif
5000         
5001         o = vm_call_method(getmid, *global_ref_table, lobj);
5002
5003         refcount = (java_lang_Integer *) o;
5004
5005         if (refcount == NULL) {
5006                 newval = native_new_and_init_int(class_java_lang_Integer, 1);
5007
5008                 if (newval == NULL) {
5009 #if defined(USE_THREADS)
5010                         builtin_monitorexit(*global_ref_table);
5011 #endif
5012                         return NULL;
5013                 }
5014
5015                 (void) vm_call_method(putmid, *global_ref_table, lobj, newval);
5016
5017         } else {
5018                 /* we can access the object itself, as we are in a
5019            synchronized section */
5020
5021                 refcount->value++;
5022         }
5023
5024 #if defined(USE_THREADS)
5025         builtin_monitorexit(*global_ref_table);
5026 #endif
5027
5028         return lobj;
5029 }
5030
5031
5032 /* DeleteGlobalRef *************************************************************
5033
5034    Deletes the global reference pointed to by globalRef.
5035
5036 *******************************************************************************/
5037
5038 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5039 {
5040         java_objectheader *o;
5041         java_lang_Integer *refcount;
5042         s4                 val;
5043
5044         STATISTICS(jniinvokation());
5045
5046 #if defined(USE_THREADS)
5047         builtin_monitorenter(*global_ref_table);
5048 #endif
5049
5050         o = vm_call_method(getmid, *global_ref_table, globalRef);
5051
5052         refcount = (java_lang_Integer *) o;
5053
5054         if (refcount == NULL) {
5055                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
5056                 return;
5057         }
5058
5059         /* we can access the object itself, as we are in a synchronized
5060            section */
5061
5062         val = refcount->value - 1;
5063
5064         if (val == 0) {
5065                 (void) vm_call_method(removemid, *global_ref_table, refcount);
5066
5067         } else {
5068                 /* we do not create a new object, but set the new value into
5069            the old one */
5070
5071                 refcount->value = val;
5072         }
5073
5074 #if defined(USE_THREADS)
5075         builtin_monitorexit(*global_ref_table);
5076 #endif
5077 }
5078
5079
5080 /* ExceptionCheck **************************************************************
5081
5082    Returns JNI_TRUE when there is a pending exception; otherwise,
5083    returns JNI_FALSE.
5084
5085 *******************************************************************************/
5086
5087 jboolean ExceptionCheck(JNIEnv *env)
5088 {
5089         STATISTICS(jniinvokation());
5090
5091         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
5092 }
5093
5094
5095 /* New JNI 1.4 functions ******************************************************/
5096
5097 /* NewDirectByteBuffer *********************************************************
5098
5099    Allocates and returns a direct java.nio.ByteBuffer referring to the
5100    block of memory starting at the memory address address and
5101    extending capacity bytes.
5102
5103 *******************************************************************************/
5104
5105 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5106 {
5107         java_objectheader       *nbuf;
5108 #if SIZEOF_VOID_P == 8
5109         gnu_classpath_Pointer64 *paddress;
5110 #else
5111         gnu_classpath_Pointer32 *paddress;
5112 #endif
5113
5114         STATISTICS(jniinvokation());
5115
5116         /* alocate a gnu.classpath.Pointer{32,64} object */
5117
5118 #if SIZEOF_VOID_P == 8
5119         if (!(paddress = (gnu_classpath_Pointer64 *)
5120                   builtin_new(class_gnu_classpath_Pointer64)))
5121 #else
5122         if (!(paddress = (gnu_classpath_Pointer32 *)
5123                   builtin_new(class_gnu_classpath_Pointer32)))
5124 #endif
5125                 return NULL;
5126
5127         /* fill gnu.classpath.Pointer{32,64} with address */
5128
5129         paddress->data = (ptrint) address;
5130
5131         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5132
5133         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5134                                                          (jmethodID) dbbirw_init, NULL, paddress,
5135                                                          (jint) capacity, (jint) capacity, (jint) 0);
5136
5137         /* add local reference and return the value */
5138
5139         return NewLocalRef(env, nbuf);
5140 }
5141
5142
5143 /* GetDirectBufferAddress ******************************************************
5144
5145    Fetches and returns the starting address of the memory region
5146    referenced by the given direct java.nio.Buffer.
5147
5148 *******************************************************************************/
5149
5150 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
5151 {
5152         java_nio_DirectByteBufferImpl *nbuf;
5153 #if SIZEOF_VOID_P == 8
5154         gnu_classpath_Pointer64       *address;
5155 #else
5156         gnu_classpath_Pointer32       *address;
5157 #endif
5158
5159         STATISTICS(jniinvokation());
5160
5161         if (!builtin_instanceof(buf, class_java_nio_Buffer))
5162                 return NULL;
5163
5164         nbuf = (java_nio_DirectByteBufferImpl *) buf;
5165
5166 #if SIZEOF_VOID_P == 8
5167         address = (gnu_classpath_Pointer64 *) nbuf->address;
5168 #else
5169         address = (gnu_classpath_Pointer32 *) nbuf->address;
5170 #endif
5171
5172         return (void *) address->data;
5173 }
5174
5175
5176 /* GetDirectBufferCapacity *****************************************************
5177
5178    Fetches and returns the capacity in bytes of the memory region
5179    referenced by the given direct java.nio.Buffer.
5180
5181 *******************************************************************************/
5182
5183 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5184 {
5185         java_nio_Buffer *nbuf;
5186
5187         STATISTICS(jniinvokation());
5188
5189         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5190                 return -1;
5191
5192         nbuf = (java_nio_Buffer *) buf;
5193
5194         return (jlong) nbuf->cap;
5195 }
5196
5197
5198 /* DestroyJavaVM ***************************************************************
5199
5200    Unloads a Java VM and reclaims its resources. Only the main thread
5201    can unload the VM. The system waits until the main thread is only
5202    remaining user thread before it destroys the VM.
5203
5204 *******************************************************************************/
5205
5206 jint DestroyJavaVM(JavaVM *vm)
5207 {
5208         s4 status;
5209
5210         STATISTICS(jniinvokation());
5211
5212     status = vm_destroy(vm);
5213
5214         return status;
5215 }
5216
5217
5218 /* AttachCurrentThread *********************************************************
5219
5220    Attaches the current thread to a Java VM. Returns a JNI interface
5221    pointer in the JNIEnv argument.
5222
5223    Trying to attach a thread that is already attached is a no-op.
5224
5225    A native thread cannot be attached simultaneously to two Java VMs.
5226
5227    When a thread is attached to the VM, the context class loader is
5228    the bootstrap loader.
5229
5230 *******************************************************************************/
5231
5232 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
5233 {
5234         STATISTICS(jniinvokation());
5235
5236         log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
5237
5238 #if !defined(HAVE___THREAD)
5239 /*      cacao_thread_attach();*/
5240 #else
5241         #error "No idea how to implement that. Perhaps Stefan knows"
5242 #endif
5243
5244         *env = _Jv_env;
5245
5246         return 0;
5247 }
5248
5249
5250 jint DetachCurrentThread(JavaVM *vm)
5251 {
5252         STATISTICS(jniinvokation());
5253
5254         log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
5255
5256         return 0;
5257 }
5258
5259
5260 /* GetEnv **********************************************************************
5261
5262    If the current thread is not attached to the VM, sets *env to NULL,
5263    and returns JNI_EDETACHED. If the specified version is not
5264    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5265    sets *env to the appropriate interface, and returns JNI_OK.
5266
5267 *******************************************************************************/
5268
5269 jint GetEnv(JavaVM *vm, void **env, jint version)
5270 {
5271         STATISTICS(jniinvokation());
5272
5273 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5274         if (thread_getself() == NULL) {
5275                 *env = NULL;
5276
5277                 return JNI_EDETACHED;
5278         }
5279 #endif
5280
5281         if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
5282                 (version == JNI_VERSION_1_4)) {
5283                 *env = _Jv_env;
5284
5285                 return JNI_OK;
5286         }
5287
5288 #if defined(ENABLE_JVMTI)
5289         if (version == JVMTI_VERSION_1_0) {
5290                 *env = (void *) new_jvmtienv();
5291
5292                 if (env != NULL)
5293                         return JNI_OK;
5294         }
5295 #endif
5296         
5297         *env = NULL;
5298
5299         return JNI_EVERSION;
5300 }
5301
5302
5303
5304 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
5305 {
5306         STATISTICS(jniinvokation());
5307
5308         log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
5309
5310         return 0;
5311 }
5312
5313
5314 /* JNI invocation table *******************************************************/
5315
5316 const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
5317         NULL,
5318         NULL,
5319         NULL,
5320
5321         DestroyJavaVM,
5322         AttachCurrentThread,
5323         DetachCurrentThread,
5324         GetEnv,
5325         AttachCurrentThreadAsDaemon
5326 };
5327
5328
5329 /* JNI function table *********************************************************/
5330
5331 struct JNINativeInterface _Jv_JNINativeInterface = {
5332         NULL,
5333         NULL,
5334         NULL,
5335         NULL,    
5336         GetVersion,
5337
5338         DefineClass,
5339         FindClass,
5340         FromReflectedMethod,
5341         FromReflectedField,
5342         ToReflectedMethod,
5343         GetSuperclass,
5344         IsAssignableFrom,
5345         ToReflectedField,
5346
5347         Throw,
5348         ThrowNew,
5349         ExceptionOccurred,
5350         ExceptionDescribe,
5351         ExceptionClear,
5352         FatalError,
5353         PushLocalFrame,
5354         PopLocalFrame,
5355
5356         NewGlobalRef,
5357         DeleteGlobalRef,
5358         DeleteLocalRef,
5359         IsSameObject,
5360         NewLocalRef,
5361         EnsureLocalCapacity,
5362
5363         AllocObject,
5364         NewObject,
5365         NewObjectV,
5366         NewObjectA,
5367
5368         GetObjectClass,
5369         IsInstanceOf,
5370
5371         GetMethodID,
5372
5373         CallObjectMethod,
5374         CallObjectMethodV,
5375         CallObjectMethodA,
5376         CallBooleanMethod,
5377         CallBooleanMethodV,
5378         CallBooleanMethodA,
5379         CallByteMethod,
5380         CallByteMethodV,
5381         CallByteMethodA,
5382         CallCharMethod,
5383         CallCharMethodV,
5384         CallCharMethodA,
5385         CallShortMethod,
5386         CallShortMethodV,
5387         CallShortMethodA,
5388         CallIntMethod,
5389         CallIntMethodV,
5390         CallIntMethodA,
5391         CallLongMethod,
5392         CallLongMethodV,
5393         CallLongMethodA,
5394         CallFloatMethod,
5395         CallFloatMethodV,
5396         CallFloatMethodA,
5397         CallDoubleMethod,
5398         CallDoubleMethodV,
5399         CallDoubleMethodA,
5400         CallVoidMethod,
5401         CallVoidMethodV,
5402         CallVoidMethodA,
5403
5404         CallNonvirtualObjectMethod,
5405         CallNonvirtualObjectMethodV,
5406         CallNonvirtualObjectMethodA,
5407         CallNonvirtualBooleanMethod,
5408         CallNonvirtualBooleanMethodV,
5409         CallNonvirtualBooleanMethodA,
5410         CallNonvirtualByteMethod,
5411         CallNonvirtualByteMethodV,
5412         CallNonvirtualByteMethodA,
5413         CallNonvirtualCharMethod,
5414         CallNonvirtualCharMethodV,
5415         CallNonvirtualCharMethodA,
5416         CallNonvirtualShortMethod,
5417         CallNonvirtualShortMethodV,
5418         CallNonvirtualShortMethodA,
5419         CallNonvirtualIntMethod,
5420         CallNonvirtualIntMethodV,
5421         CallNonvirtualIntMethodA,
5422         CallNonvirtualLongMethod,
5423         CallNonvirtualLongMethodV,
5424         CallNonvirtualLongMethodA,
5425         CallNonvirtualFloatMethod,
5426         CallNonvirtualFloatMethodV,
5427         CallNonvirtualFloatMethodA,
5428         CallNonvirtualDoubleMethod,
5429         CallNonvirtualDoubleMethodV,
5430         CallNonvirtualDoubleMethodA,
5431         CallNonvirtualVoidMethod,
5432         CallNonvirtualVoidMethodV,
5433         CallNonvirtualVoidMethodA,
5434
5435         GetFieldID,
5436
5437         GetObjectField,
5438         GetBooleanField,
5439         GetByteField,
5440         GetCharField,
5441         GetShortField,
5442         GetIntField,
5443         GetLongField,
5444         GetFloatField,
5445         GetDoubleField,
5446         SetObjectField,
5447         SetBooleanField,
5448         SetByteField,
5449         SetCharField,
5450         SetShortField,
5451         SetIntField,
5452         SetLongField,
5453         SetFloatField,
5454         SetDoubleField,
5455
5456         GetStaticMethodID,
5457
5458         CallStaticObjectMethod,
5459         CallStaticObjectMethodV,
5460         CallStaticObjectMethodA,
5461         CallStaticBooleanMethod,
5462         CallStaticBooleanMethodV,
5463         CallStaticBooleanMethodA,
5464         CallStaticByteMethod,
5465         CallStaticByteMethodV,
5466         CallStaticByteMethodA,
5467         CallStaticCharMethod,
5468         CallStaticCharMethodV,
5469         CallStaticCharMethodA,
5470         CallStaticShortMethod,
5471         CallStaticShortMethodV,
5472         CallStaticShortMethodA,
5473         CallStaticIntMethod,
5474         CallStaticIntMethodV,
5475         CallStaticIntMethodA,
5476         CallStaticLongMethod,
5477         CallStaticLongMethodV,
5478         CallStaticLongMethodA,
5479         CallStaticFloatMethod,
5480         CallStaticFloatMethodV,
5481         CallStaticFloatMethodA,
5482         CallStaticDoubleMethod,
5483         CallStaticDoubleMethodV,
5484         CallStaticDoubleMethodA,
5485         CallStaticVoidMethod,
5486         CallStaticVoidMethodV,
5487         CallStaticVoidMethodA,
5488
5489         GetStaticFieldID,
5490
5491         GetStaticObjectField,
5492         GetStaticBooleanField,
5493         GetStaticByteField,
5494         GetStaticCharField,
5495         GetStaticShortField,
5496         GetStaticIntField,
5497         GetStaticLongField,
5498         GetStaticFloatField,
5499         GetStaticDoubleField,
5500         SetStaticObjectField,
5501         SetStaticBooleanField,
5502         SetStaticByteField,
5503         SetStaticCharField,
5504         SetStaticShortField,
5505         SetStaticIntField,
5506         SetStaticLongField,
5507         SetStaticFloatField,
5508         SetStaticDoubleField,
5509
5510         NewString,
5511         GetStringLength,
5512         GetStringChars,
5513         ReleaseStringChars,
5514
5515         NewStringUTF,
5516         GetStringUTFLength,
5517         GetStringUTFChars,
5518         ReleaseStringUTFChars,
5519
5520         GetArrayLength,
5521
5522         NewObjectArray,
5523         GetObjectArrayElement,
5524         SetObjectArrayElement,
5525
5526         NewBooleanArray,
5527         NewByteArray,
5528         NewCharArray,
5529         NewShortArray,
5530         NewIntArray,
5531         NewLongArray,
5532         NewFloatArray,
5533         NewDoubleArray,
5534
5535         GetBooleanArrayElements,
5536         GetByteArrayElements,
5537         GetCharArrayElements,
5538         GetShortArrayElements,
5539         GetIntArrayElements,
5540         GetLongArrayElements,
5541         GetFloatArrayElements,
5542         GetDoubleArrayElements,
5543
5544         ReleaseBooleanArrayElements,
5545         ReleaseByteArrayElements,
5546         ReleaseCharArrayElements,
5547         ReleaseShortArrayElements,
5548         ReleaseIntArrayElements,
5549         ReleaseLongArrayElements,
5550         ReleaseFloatArrayElements,
5551         ReleaseDoubleArrayElements,
5552
5553         GetBooleanArrayRegion,
5554         GetByteArrayRegion,
5555         GetCharArrayRegion,
5556         GetShortArrayRegion,
5557         GetIntArrayRegion,
5558         GetLongArrayRegion,
5559         GetFloatArrayRegion,
5560         GetDoubleArrayRegion,
5561         SetBooleanArrayRegion,
5562         SetByteArrayRegion,
5563         SetCharArrayRegion,
5564         SetShortArrayRegion,
5565         SetIntArrayRegion,
5566         SetLongArrayRegion,
5567         SetFloatArrayRegion,
5568         SetDoubleArrayRegion,
5569
5570         RegisterNatives,
5571         UnregisterNatives,
5572
5573         MonitorEnter,
5574         MonitorExit,
5575
5576         GetJavaVM,
5577
5578         /* new JNI 1.2 functions */
5579
5580         GetStringRegion,
5581         GetStringUTFRegion,
5582
5583         GetPrimitiveArrayCritical,
5584         ReleasePrimitiveArrayCritical,
5585
5586         GetStringCritical,
5587         ReleaseStringCritical,
5588
5589         NewWeakGlobalRef,
5590         DeleteWeakGlobalRef,
5591
5592         ExceptionCheck,
5593
5594         /* new JNI 1.4 functions */
5595
5596         NewDirectByteBuffer,
5597         GetDirectBufferAddress,
5598         GetDirectBufferCapacity
5599 };
5600
5601
5602 /* Invocation API Functions ***************************************************/
5603
5604 /* JNI_GetDefaultJavaVMInitArgs ************************************************
5605
5606    Returns a default configuration for the Java VM.
5607
5608 *******************************************************************************/
5609
5610 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
5611 {
5612         JavaVMInitArgs *_vm_args;
5613
5614         _vm_args = (JavaVMInitArgs *) vm_args;
5615
5616         /* GNU classpath currently supports JNI 1.2 */
5617
5618         switch (_vm_args->version) {
5619     case JNI_VERSION_1_1:
5620                 _vm_args->version = JNI_VERSION_1_1;
5621                 break;
5622
5623     case JNI_VERSION_1_2:
5624     case JNI_VERSION_1_4:
5625                 _vm_args->ignoreUnrecognized = JNI_FALSE;
5626                 _vm_args->options = NULL;
5627                 _vm_args->nOptions = 0;
5628                 break;
5629
5630     default:
5631                 return -1;
5632         }
5633   
5634         return 0;
5635 }
5636
5637
5638 /* JNI_GetCreatedJavaVMs *******************************************************
5639
5640    Returns all Java VMs that have been created. Pointers to VMs are written in
5641    the buffer vmBuf in the order they are created. At most bufLen number of
5642    entries will be written. The total number of created VMs is returned in
5643    *nVMs.
5644
5645 *******************************************************************************/
5646
5647 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
5648 {
5649         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
5650
5651         return 0;
5652 }
5653
5654
5655 /* JNI_CreateJavaVM ************************************************************
5656
5657    Loads and initializes a Java VM. The current thread becomes the main thread.
5658    Sets the env argument to the JNI interface pointer of the main thread.
5659
5660 *******************************************************************************/
5661
5662 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
5663 {
5664         JavaVMInitArgs *_vm_args;
5665         _Jv_JNIEnv     *env;
5666         _Jv_JavaVM     *jvm;
5667         localref_table *lrt;
5668
5669         /* get the arguments for the new JVM */
5670
5671         _vm_args = (JavaVMInitArgs *) vm_args;
5672
5673         /* get the VM and Env tables (must be set before vm_create) */
5674
5675         env = NEW(_Jv_JNIEnv);
5676         env->env = &_Jv_JNINativeInterface;
5677
5678         /* XXX Set the global variable.  Maybe we should do that differently. */
5679
5680         _Jv_env = env;
5681
5682         /* actually create the JVM */
5683
5684         if (!vm_create(_vm_args))
5685                 return -1;
5686
5687         /* create and fill a JavaVM structure */
5688
5689         jvm = NEW(_Jv_JavaVM);
5690         jvm->functions = &_Jv_JNIInvokeInterface;
5691
5692         /* XXX Set the global variable.  Maybe we should do that differently. */
5693
5694         _Jv_jvm = jvm;
5695
5696         /* setup the local ref table (must be created after vm_create) */
5697
5698         lrt = GCNEW(localref_table);
5699
5700         lrt->capacity    = LOCALREFTABLE_CAPACITY;
5701         lrt->used        = 0;
5702         lrt->localframes = 1;
5703         lrt->prev        = LOCALREFTABLE;
5704
5705         /* clear the references array (memset is faster then a for-loop) */
5706
5707         MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
5708
5709         LOCALREFTABLE = lrt;
5710
5711         /* now return the values */
5712
5713         *p_vm  = (JavaVM *) jvm;
5714         *p_env = (void *) env;
5715
5716         return 0;
5717 }
5718
5719
5720 /*
5721  * These are local overrides for various environment variables in Emacs.
5722  * Please do not remove this and leave it at the end of the file, where
5723  * Emacs will automagically detect them.
5724  * ---------------------------------------------------------------------
5725  * Local variables:
5726  * mode: c
5727  * indent-tabs-mode: t
5728  * c-basic-offset: 4
5729  * tab-width: 4
5730  * End:
5731  * vim:noexpandtab:sw=4:ts=4:
5732  */