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