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