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