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