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