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