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