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