Merged revisions 7766-7796 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 7723 2007-04-16 18:03:08Z 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  = (java_lang_String *) 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
4183    characters.
4184
4185 *******************************************************************************/
4186
4187 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
4188 {
4189         java_lang_String *s;
4190
4191         STATISTICS(jniinvokation());
4192
4193         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
4194
4195     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
4196 }
4197
4198
4199 /****************** returns the utf8 length in bytes of a string *******************/
4200
4201 jsize _Jv_JNI_GetStringUTFLength (JNIEnv *env, jstring string)
4202 {   
4203     java_lang_String *s = (java_lang_String*) string;
4204
4205         STATISTICS(jniinvokation());
4206
4207     return (jsize) u2_utflength(s->value->data, s->count); 
4208 }
4209
4210
4211 /* GetStringUTFChars ***********************************************************
4212
4213    Returns a pointer to an array of UTF-8 characters of the
4214    string. This array is valid until it is released by
4215    ReleaseStringUTFChars().
4216
4217 *******************************************************************************/
4218
4219 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
4220                                                                           jboolean *isCopy)
4221 {
4222         utf *u;
4223
4224         STATISTICS(jniinvokation());
4225
4226         if (string == NULL)
4227                 return "";
4228
4229         if (isCopy)
4230                 *isCopy = JNI_TRUE;
4231         
4232         u = javastring_toutf((java_objectheader *) string, false);
4233
4234         if (u != NULL)
4235                 return u->text;
4236
4237         return "";
4238 }
4239
4240
4241 /* ReleaseStringUTFChars *******************************************************
4242
4243    Informs the VM that the native code no longer needs access to
4244    utf. The utf argument is a pointer derived from string using
4245    GetStringUTFChars().
4246
4247 *******************************************************************************/
4248
4249 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
4250 {
4251         STATISTICS(jniinvokation());
4252
4253     /* XXX we don't release utf chars right now, perhaps that should be done 
4254            later. Since there is always one reference the garbage collector will
4255            never get them */
4256 }
4257
4258
4259 /* Array Operations ***********************************************************/
4260
4261 /* GetArrayLength **************************************************************
4262
4263    Returns the number of elements in the array.
4264
4265 *******************************************************************************/
4266
4267 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
4268 {
4269         java_arrayheader *a;
4270
4271         STATISTICS(jniinvokation());
4272
4273         a = (java_arrayheader *) array;
4274
4275         return a->size;
4276 }
4277
4278
4279 /* NewObjectArray **************************************************************
4280
4281    Constructs a new array holding objects in class elementClass. All
4282    elements are initially set to initialElement.
4283
4284 *******************************************************************************/
4285
4286 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
4287                                                                         jclass elementClass, jobject initialElement)
4288 {
4289         java_objectarray *oa;
4290         s4                i;
4291
4292         STATISTICS(jniinvokation());
4293
4294         if (length < 0) {
4295                 exceptions_throw_negativearraysizeexception();
4296                 return NULL;
4297         }
4298
4299     oa = builtin_anewarray(length, elementClass);
4300
4301         if (oa == NULL)
4302                 return NULL;
4303
4304         /* set all elements to initialElement */
4305
4306         for (i = 0; i < length; i++)
4307                 oa->data[i] = initialElement;
4308
4309         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
4310 }
4311
4312
4313 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
4314                                                                           jsize index)
4315 {
4316         java_objectarray *oa;
4317         jobject           o;
4318
4319         STATISTICS(jniinvokation());
4320
4321         oa = (java_objectarray *) array;
4322
4323         if (index >= oa->header.size) {
4324                 exceptions_throw_arrayindexoutofboundsexception();
4325                 return NULL;
4326         }
4327
4328         o = oa->data[index];
4329
4330         return _Jv_JNI_NewLocalRef(env, o);
4331 }
4332
4333
4334 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
4335                                                                    jsize index, jobject val)
4336 {
4337         java_objectarray  *oa;
4338         java_objectheader *o;
4339
4340         STATISTICS(jniinvokation());
4341
4342         oa = (java_objectarray *) array;
4343         o  = (java_objectheader *) val;
4344
4345         if (index >= oa->header.size) {
4346                 exceptions_throw_arrayindexoutofboundsexception();
4347                 return;
4348         }
4349
4350         /* check if the class of value is a subclass of the element class
4351            of the array */
4352
4353         if (!builtin_canstore(oa, o))
4354                 return;
4355
4356         oa->data[index] = val;
4357 }
4358
4359
4360 jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
4361 {
4362         java_booleanarray *ba;
4363
4364         STATISTICS(jniinvokation());
4365
4366         if (len < 0) {
4367                 exceptions_throw_negativearraysizeexception();
4368                 return NULL;
4369         }
4370
4371         ba = builtin_newarray_boolean(len);
4372
4373         return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4374 }
4375
4376
4377 jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
4378 {
4379         java_bytearray *ba;
4380
4381         STATISTICS(jniinvokation());
4382
4383         if (len < 0) {
4384                 exceptions_throw_negativearraysizeexception();
4385                 return NULL;
4386         }
4387
4388         ba = builtin_newarray_byte(len);
4389
4390         return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4391 }
4392
4393
4394 jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
4395 {
4396         java_chararray *ca;
4397
4398         STATISTICS(jniinvokation());
4399
4400         if (len < 0) {
4401                 exceptions_throw_negativearraysizeexception();
4402                 return NULL;
4403         }
4404
4405         ca = builtin_newarray_char(len);
4406
4407         return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
4408 }
4409
4410
4411 jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
4412 {
4413         java_shortarray *sa;
4414
4415         STATISTICS(jniinvokation());
4416
4417         if (len < 0) {
4418                 exceptions_throw_negativearraysizeexception();
4419                 return NULL;
4420         }
4421
4422         sa = builtin_newarray_short(len);
4423
4424         return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
4425 }
4426
4427
4428 jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
4429 {
4430         java_intarray *ia;
4431
4432         STATISTICS(jniinvokation());
4433
4434         if (len < 0) {
4435                 exceptions_throw_negativearraysizeexception();
4436                 return NULL;
4437         }
4438
4439         ia = builtin_newarray_int(len);
4440
4441         return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
4442 }
4443
4444
4445 jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
4446 {
4447         java_longarray *la;
4448
4449         STATISTICS(jniinvokation());
4450
4451         if (len < 0) {
4452                 exceptions_throw_negativearraysizeexception();
4453                 return NULL;
4454         }
4455
4456         la = builtin_newarray_long(len);
4457
4458         return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
4459 }
4460
4461
4462 jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
4463 {
4464         java_floatarray *fa;
4465
4466         STATISTICS(jniinvokation());
4467
4468         if (len < 0) {
4469                 exceptions_throw_negativearraysizeexception();
4470                 return NULL;
4471         }
4472
4473         fa = builtin_newarray_float(len);
4474
4475         return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
4476 }
4477
4478
4479 jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
4480 {
4481         java_doublearray *da;
4482
4483         STATISTICS(jniinvokation());
4484
4485         if (len < 0) {
4486                 exceptions_throw_negativearraysizeexception();
4487                 return NULL;
4488         }
4489
4490         da = builtin_newarray_double(len);
4491
4492         return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
4493 }
4494
4495
4496 /* Get<PrimitiveType>ArrayElements *********************************************
4497
4498    A family of functions that returns the body of the primitive array.
4499
4500 *******************************************************************************/
4501
4502 jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4503                                                                                   jboolean *isCopy)
4504 {
4505         java_booleanarray *ba;
4506
4507         STATISTICS(jniinvokation());
4508
4509         ba = (java_booleanarray *) array;
4510
4511         if (isCopy)
4512                 *isCopy = JNI_FALSE;
4513
4514         return ba->data;
4515 }
4516
4517
4518 jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
4519                                                                         jboolean *isCopy)
4520 {
4521         java_bytearray *ba;
4522
4523         STATISTICS(jniinvokation());
4524
4525         ba = (java_bytearray *) array;
4526
4527         if (isCopy)
4528                 *isCopy = JNI_FALSE;
4529
4530         return ba->data;
4531 }
4532
4533
4534 jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
4535                                                                         jboolean *isCopy)
4536 {
4537         java_chararray *ca;
4538
4539         STATISTICS(jniinvokation());
4540
4541         ca = (java_chararray *) array;
4542
4543         if (isCopy)
4544                 *isCopy = JNI_FALSE;
4545
4546         return ca->data;
4547 }
4548
4549
4550 jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
4551                                                                           jboolean *isCopy)
4552 {
4553         java_shortarray *sa;
4554
4555         STATISTICS(jniinvokation());
4556
4557         sa = (java_shortarray *) array;
4558
4559         if (isCopy)
4560                 *isCopy = JNI_FALSE;
4561
4562         return sa->data;
4563 }
4564
4565
4566 jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
4567                                                                   jboolean *isCopy)
4568 {
4569         java_intarray *ia;
4570
4571         STATISTICS(jniinvokation());
4572
4573         ia = (java_intarray *) array;
4574
4575         if (isCopy)
4576                 *isCopy = JNI_FALSE;
4577
4578         return ia->data;
4579 }
4580
4581
4582 jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
4583                                                                         jboolean *isCopy)
4584 {
4585         java_longarray *la;
4586
4587         STATISTICS(jniinvokation());
4588
4589         la = (java_longarray *) array;
4590
4591         if (isCopy)
4592                 *isCopy = JNI_FALSE;
4593
4594         /* We cast this one to prevent a compiler warning on 64-bit
4595            systems since GNU Classpath typedef jlong to long long. */
4596
4597         return (jlong *) la->data;
4598 }
4599
4600
4601 jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
4602                                                                           jboolean *isCopy)
4603 {
4604         java_floatarray *fa;
4605
4606         STATISTICS(jniinvokation());
4607
4608         fa = (java_floatarray *) array;
4609
4610         if (isCopy)
4611                 *isCopy = JNI_FALSE;
4612
4613         return fa->data;
4614 }
4615
4616
4617 jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4618                                                                                 jboolean *isCopy)
4619 {
4620         java_doublearray *da;
4621
4622         STATISTICS(jniinvokation());
4623
4624         da = (java_doublearray *) array;
4625
4626         if (isCopy)
4627                 *isCopy = JNI_FALSE;
4628
4629         return da->data;
4630 }
4631
4632
4633 /* Release<PrimitiveType>ArrayElements *****************************************
4634
4635    A family of functions that informs the VM that the native code no
4636    longer needs access to elems. The elems argument is a pointer
4637    derived from array using the corresponding
4638    Get<PrimitiveType>ArrayElements() function. If necessary, this
4639    function copies back all changes made to elems to the original
4640    array.
4641
4642 *******************************************************************************/
4643
4644 void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4645                                                                                  jboolean *elems, jint mode)
4646 {
4647         java_booleanarray *ba;
4648
4649         STATISTICS(jniinvokation());
4650
4651         ba = (java_booleanarray *) array;
4652
4653         if (elems != ba->data) {
4654                 switch (mode) {
4655                 case JNI_COMMIT:
4656                         MCOPY(ba->data, elems, u1, ba->header.size);
4657                         break;
4658                 case 0:
4659                         MCOPY(ba->data, elems, u1, ba->header.size);
4660                         /* XXX TWISTI how should it be freed? */
4661                         break;
4662                 case JNI_ABORT:
4663                         /* XXX TWISTI how should it be freed? */
4664                         break;
4665                 }
4666         }
4667 }
4668
4669
4670 void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
4671                                                                           jbyte *elems, jint mode)
4672 {
4673         java_bytearray *ba;
4674
4675         STATISTICS(jniinvokation());
4676
4677         ba = (java_bytearray *) array;
4678
4679         if (elems != ba->data) {
4680                 switch (mode) {
4681                 case JNI_COMMIT:
4682                         MCOPY(ba->data, elems, s1, ba->header.size);
4683                         break;
4684                 case 0:
4685                         MCOPY(ba->data, elems, s1, ba->header.size);
4686                         /* XXX TWISTI how should it be freed? */
4687                         break;
4688                 case JNI_ABORT:
4689                         /* XXX TWISTI how should it be freed? */
4690                         break;
4691                 }
4692         }
4693 }
4694
4695
4696 void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
4697                                                                           jchar *elems, jint mode)
4698 {
4699         java_chararray *ca;
4700
4701         STATISTICS(jniinvokation());
4702
4703         ca = (java_chararray *) array;
4704
4705         if (elems != ca->data) {
4706                 switch (mode) {
4707                 case JNI_COMMIT:
4708                         MCOPY(ca->data, elems, u2, ca->header.size);
4709                         break;
4710                 case 0:
4711                         MCOPY(ca->data, elems, u2, ca->header.size);
4712                         /* XXX TWISTI how should it be freed? */
4713                         break;
4714                 case JNI_ABORT:
4715                         /* XXX TWISTI how should it be freed? */
4716                         break;
4717                 }
4718         }
4719 }
4720
4721
4722 void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
4723                                                                            jshort *elems, jint mode)
4724 {
4725         java_shortarray *sa;
4726
4727         STATISTICS(jniinvokation());
4728
4729         sa = (java_shortarray *) array;
4730
4731         if (elems != sa->data) {
4732                 switch (mode) {
4733                 case JNI_COMMIT:
4734                         MCOPY(sa->data, elems, s2, sa->header.size);
4735                         break;
4736                 case 0:
4737                         MCOPY(sa->data, elems, s2, sa->header.size);
4738                         /* XXX TWISTI how should it be freed? */
4739                         break;
4740                 case JNI_ABORT:
4741                         /* XXX TWISTI how should it be freed? */
4742                         break;
4743                 }
4744         }
4745 }
4746
4747
4748 void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4749                                                                          jint mode)
4750 {
4751         java_intarray *ia;
4752
4753         STATISTICS(jniinvokation());
4754
4755         ia = (java_intarray *) array;
4756
4757         if (elems != ia->data) {
4758                 switch (mode) {
4759                 case JNI_COMMIT:
4760                         MCOPY(ia->data, elems, s4, ia->header.size);
4761                         break;
4762                 case 0:
4763                         MCOPY(ia->data, elems, s4, ia->header.size);
4764                         /* XXX TWISTI how should it be freed? */
4765                         break;
4766                 case JNI_ABORT:
4767                         /* XXX TWISTI how should it be freed? */
4768                         break;
4769                 }
4770         }
4771 }
4772
4773
4774 void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
4775                                                                           jlong *elems, jint mode)
4776 {
4777         java_longarray *la;
4778
4779         STATISTICS(jniinvokation());
4780
4781         la = (java_longarray *) array;
4782
4783         /* We cast this one to prevent a compiler warning on 64-bit
4784            systems since GNU Classpath typedef jlong to long long. */
4785
4786         if ((s8 *) elems != la->data) {
4787                 switch (mode) {
4788                 case JNI_COMMIT:
4789                         MCOPY(la->data, elems, s8, la->header.size);
4790                         break;
4791                 case 0:
4792                         MCOPY(la->data, elems, s8, la->header.size);
4793                         /* XXX TWISTI how should it be freed? */
4794                         break;
4795                 case JNI_ABORT:
4796                         /* XXX TWISTI how should it be freed? */
4797                         break;
4798                 }
4799         }
4800 }
4801
4802
4803 void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
4804                                                                            jfloat *elems, jint mode)
4805 {
4806         java_floatarray *fa;
4807
4808         STATISTICS(jniinvokation());
4809
4810         fa = (java_floatarray *) array;
4811
4812         if (elems != fa->data) {
4813                 switch (mode) {
4814                 case JNI_COMMIT:
4815                         MCOPY(fa->data, elems, float, fa->header.size);
4816                         break;
4817                 case 0:
4818                         MCOPY(fa->data, elems, float, fa->header.size);
4819                         /* XXX TWISTI how should it be freed? */
4820                         break;
4821                 case JNI_ABORT:
4822                         /* XXX TWISTI how should it be freed? */
4823                         break;
4824                 }
4825         }
4826 }
4827
4828
4829 void _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4830                                                                                 jdouble *elems, jint mode)
4831 {
4832         java_doublearray *da;
4833
4834         STATISTICS(jniinvokation());
4835
4836         da = (java_doublearray *) array;
4837
4838         if (elems != da->data) {
4839                 switch (mode) {
4840                 case JNI_COMMIT:
4841                         MCOPY(da->data, elems, double, da->header.size);
4842                         break;
4843                 case 0:
4844                         MCOPY(da->data, elems, double, da->header.size);
4845                         /* XXX TWISTI how should it be freed? */
4846                         break;
4847                 case JNI_ABORT:
4848                         /* XXX TWISTI how should it be freed? */
4849                         break;
4850                 }
4851         }
4852 }
4853
4854
4855 /*  Get<PrimitiveType>ArrayRegion **********************************************
4856
4857         A family of functions that copies a region of a primitive array
4858         into a buffer.
4859
4860 *******************************************************************************/
4861
4862 void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
4863                                                                    jsize start, jsize len, jboolean *buf)
4864 {
4865         java_booleanarray *ba;
4866
4867         STATISTICS(jniinvokation());
4868
4869         ba = (java_booleanarray *) array;
4870
4871     if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4872                 exceptions_throw_arrayindexoutofboundsexception();
4873     else
4874                 MCOPY(buf, &ba->data[start], u1, len);
4875 }
4876
4877
4878 void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
4879                                                                 jsize len, jbyte *buf)
4880 {
4881         java_bytearray *ba;
4882
4883         STATISTICS(jniinvokation());
4884
4885         ba = (java_bytearray *) array;
4886
4887         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4888                 exceptions_throw_arrayindexoutofboundsexception();
4889         else
4890                 MCOPY(buf, &ba->data[start], s1, len);
4891 }
4892
4893
4894 void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
4895                                                                 jsize len, jchar *buf)
4896 {
4897         java_chararray *ca;
4898
4899         STATISTICS(jniinvokation());
4900
4901         ca = (java_chararray *) array;
4902
4903         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4904                 exceptions_throw_arrayindexoutofboundsexception();
4905         else
4906                 MCOPY(buf, &ca->data[start], u2, len);
4907 }
4908
4909
4910 void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4911                                                                  jsize len, jshort *buf)
4912 {
4913         java_shortarray *sa;
4914
4915         STATISTICS(jniinvokation());
4916
4917         sa = (java_shortarray *) array;
4918
4919         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4920                 exceptions_throw_arrayindexoutofboundsexception();
4921         else    
4922                 MCOPY(buf, &sa->data[start], s2, len);
4923 }
4924
4925
4926 void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
4927                                                            jsize len, jint *buf)
4928 {
4929         java_intarray *ia;
4930
4931         STATISTICS(jniinvokation());
4932
4933         ia = (java_intarray *) array;
4934
4935         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4936                 exceptions_throw_arrayindexoutofboundsexception();
4937         else
4938                 MCOPY(buf, &ia->data[start], s4, len);
4939 }
4940
4941
4942 void _Jv_JNI_GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start,
4943                                                                 jsize len, jlong *buf)
4944 {
4945         java_longarray *la;
4946
4947         STATISTICS(jniinvokation());
4948
4949         la = (java_longarray *) array;
4950
4951         if ((start < 0) || (len < 0) || (start + len > la->header.size))
4952                 exceptions_throw_arrayindexoutofboundsexception();
4953         else
4954                 MCOPY(buf, &la->data[start], s8, len);
4955 }
4956
4957
4958 void _Jv_JNI_GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4959                                                                  jsize len, jfloat *buf)
4960 {
4961         java_floatarray *fa;
4962
4963         STATISTICS(jniinvokation());
4964
4965         fa = (java_floatarray *) array;
4966
4967         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4968                 exceptions_throw_arrayindexoutofboundsexception();
4969         else
4970                 MCOPY(buf, &fa->data[start], float, len);
4971 }
4972
4973
4974 void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4975                                                                   jsize len, jdouble *buf)
4976 {
4977         java_doublearray *da;
4978
4979         STATISTICS(jniinvokation());
4980
4981         da = (java_doublearray *) array;
4982
4983         if ((start < 0) || (len < 0) || (start + len > da->header.size))
4984                 exceptions_throw_arrayindexoutofboundsexception();
4985         else
4986                 MCOPY(buf, &da->data[start], double, len);
4987 }
4988
4989
4990 /*  Set<PrimitiveType>ArrayRegion **********************************************
4991
4992         A family of functions that copies back a region of a primitive
4993         array from a buffer.
4994
4995 *******************************************************************************/
4996
4997 void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
4998                                                                    jsize start, jsize len, jboolean *buf)
4999 {
5000         java_booleanarray *ba;
5001
5002         STATISTICS(jniinvokation());
5003
5004         ba = (java_booleanarray *) array;
5005
5006         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5007                 exceptions_throw_arrayindexoutofboundsexception();
5008         else
5009                 MCOPY(&ba->data[start], buf, u1, len);
5010 }
5011
5012
5013 void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
5014                                                                 jsize len, jbyte *buf)
5015 {
5016         java_bytearray *ba;
5017
5018         STATISTICS(jniinvokation());
5019
5020         ba = (java_bytearray *) array;
5021
5022         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
5023                 exceptions_throw_arrayindexoutofboundsexception();
5024         else
5025                 MCOPY(&ba->data[start], buf, s1, len);
5026 }
5027
5028
5029 void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
5030                                                                 jsize len, jchar *buf)
5031 {
5032         java_chararray *ca;
5033
5034         STATISTICS(jniinvokation());
5035
5036         ca = (java_chararray *) array;
5037
5038         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
5039                 exceptions_throw_arrayindexoutofboundsexception();
5040         else
5041                 MCOPY(&ca->data[start], buf, u2, len);
5042 }
5043
5044
5045 void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
5046                                                                  jsize len, jshort *buf)
5047 {
5048         java_shortarray *sa;
5049
5050         STATISTICS(jniinvokation());
5051
5052         sa = (java_shortarray *) array;
5053
5054         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5055                 exceptions_throw_arrayindexoutofboundsexception();
5056         else
5057                 MCOPY(&sa->data[start], buf, s2, len);
5058 }
5059
5060
5061 void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5062                                                            jsize len, jint *buf)
5063 {
5064         java_intarray *ia;
5065
5066         STATISTICS(jniinvokation());
5067
5068         ia = (java_intarray *) array;
5069
5070         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5071                 exceptions_throw_arrayindexoutofboundsexception();
5072         else
5073                 MCOPY(&ia->data[start], buf, s4, len);
5074 }
5075
5076
5077 void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
5078                                                                 jsize len, jlong *buf)
5079 {
5080         java_longarray *la;
5081
5082         STATISTICS(jniinvokation());
5083
5084         la = (java_longarray *) array;
5085
5086         if ((start < 0) || (len < 0) || (start + len > la->header.size))
5087                 exceptions_throw_arrayindexoutofboundsexception();
5088         else
5089                 MCOPY(&la->data[start], buf, s8, len);
5090 }
5091
5092
5093 void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5094                                                                  jsize len, jfloat *buf)
5095 {
5096         java_floatarray *fa;
5097
5098         STATISTICS(jniinvokation());
5099
5100         fa = (java_floatarray *) array;
5101
5102         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5103                 exceptions_throw_arrayindexoutofboundsexception();
5104         else
5105                 MCOPY(&fa->data[start], buf, float, len);
5106 }
5107
5108
5109 void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5110                                                                   jsize len, jdouble *buf)
5111 {
5112         java_doublearray *da;
5113
5114         STATISTICS(jniinvokation());
5115
5116         da = (java_doublearray *) array;
5117
5118         if ((start < 0) || (len < 0) || (start + len > da->header.size))
5119                 exceptions_throw_arrayindexoutofboundsexception();
5120         else
5121                 MCOPY(&da->data[start], buf, double, len);
5122 }
5123
5124
5125 /* Registering Native Methods *************************************************/
5126
5127 /* RegisterNatives *************************************************************
5128
5129    Registers native methods with the class specified by the clazz
5130    argument. The methods parameter specifies an array of
5131    JNINativeMethod structures that contain the names, signatures, and
5132    function pointers of the native methods. The nMethods parameter
5133    specifies the number of native methods in the array.
5134
5135 *******************************************************************************/
5136
5137 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
5138                                                          const JNINativeMethod *methods, jint nMethods)
5139 {
5140         STATISTICS(jniinvokation());
5141
5142     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
5143         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
5144         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
5145         */
5146
5147     return 0;
5148 }
5149
5150
5151 /* UnregisterNatives ***********************************************************
5152
5153    Unregisters native methods of a class. The class goes back to the
5154    state before it was linked or registered with its native method
5155    functions.
5156
5157    This function should not be used in normal native code. Instead, it
5158    provides special programs a way to reload and relink native
5159    libraries.
5160
5161 *******************************************************************************/
5162
5163 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
5164 {
5165         STATISTICS(jniinvokation());
5166
5167         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
5168
5169     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
5170
5171     return 0;
5172 }
5173
5174
5175 /* Monitor Operations *********************************************************/
5176
5177 /* MonitorEnter ****************************************************************
5178
5179    Enters the monitor associated with the underlying Java object
5180    referred to by obj.
5181
5182 *******************************************************************************/
5183
5184 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
5185 {
5186         STATISTICS(jniinvokation());
5187
5188         if (obj == NULL) {
5189                 exceptions_throw_nullpointerexception();
5190                 return JNI_ERR;
5191         }
5192
5193         LOCK_MONITOR_ENTER(obj);
5194
5195         return JNI_OK;
5196 }
5197
5198
5199 /* MonitorExit *****************************************************************
5200
5201    The current thread must be the owner of the monitor associated with
5202    the underlying Java object referred to by obj. The thread
5203    decrements the counter indicating the number of times it has
5204    entered this monitor. If the value of the counter becomes zero, the
5205    current thread releases the monitor.
5206
5207 *******************************************************************************/
5208
5209 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
5210 {
5211         STATISTICS(jniinvokation());
5212
5213         if (obj == NULL) {
5214                 exceptions_throw_nullpointerexception();
5215                 return JNI_ERR;
5216         }
5217
5218         LOCK_MONITOR_EXIT(obj);
5219
5220         return JNI_OK;
5221 }
5222
5223
5224 /* JavaVM Interface ***********************************************************/
5225
5226 /* GetJavaVM *******************************************************************
5227
5228    Returns the Java VM interface (used in the Invocation API)
5229    associated with the current thread. The result is placed at the
5230    location pointed to by the second argument, vm.
5231
5232 *******************************************************************************/
5233
5234 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
5235 {
5236         STATISTICS(jniinvokation());
5237
5238     *vm = (JavaVM *) _Jv_jvm;
5239
5240         return 0;
5241 }
5242
5243
5244 /* GetStringRegion *************************************************************
5245
5246    Copies len number of Unicode characters beginning at offset start
5247    to the given buffer buf.
5248
5249    Throws StringIndexOutOfBoundsException on index overflow.
5250
5251 *******************************************************************************/
5252
5253 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
5254                                                          jchar *buf)
5255 {
5256         java_lang_String *s;
5257         java_chararray   *ca;
5258
5259         STATISTICS(jniinvokation());
5260
5261         s  = (java_lang_String *) str;
5262         ca = s->value;
5263
5264         if ((start < 0) || (len < 0) || (start > s->count) ||
5265                 (start + len > s->count)) {
5266                 exceptions_throw_stringindexoutofboundsexception();
5267                 return;
5268         }
5269
5270         MCOPY(buf, &ca->data[start], u2, len);
5271 }
5272
5273
5274 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
5275                                                                 jsize len, char *buf)
5276 {
5277         STATISTICS(jniinvokation());
5278
5279         log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
5280 }
5281
5282
5283 /* GetPrimitiveArrayCritical ***************************************************
5284
5285    Obtain a direct pointer to array elements.
5286
5287 *******************************************************************************/
5288
5289 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
5290                                                                                 jboolean *isCopy)
5291 {
5292         java_bytearray *ba;
5293         jbyte          *bp;
5294
5295         ba = (java_bytearray *) array;
5296
5297         /* do the same as Kaffe does */
5298
5299         bp = _Jv_JNI_GetByteArrayElements(env, ba, isCopy);
5300
5301         return (void *) bp;
5302 }
5303
5304
5305 /* ReleasePrimitiveArrayCritical ***********************************************
5306
5307    No specific documentation.
5308
5309 *******************************************************************************/
5310
5311 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
5312                                                                                    void *carray, jint mode)
5313 {
5314         STATISTICS(jniinvokation());
5315
5316         /* do the same as Kaffe does */
5317
5318         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
5319                                                                          mode);
5320 }
5321
5322
5323 /* GetStringCritical ***********************************************************
5324
5325    The semantics of these two functions are similar to the existing
5326    Get/ReleaseStringChars functions.
5327
5328 *******************************************************************************/
5329
5330 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
5331                                                                            jboolean *isCopy)
5332 {
5333         STATISTICS(jniinvokation());
5334
5335         return _Jv_JNI_GetStringChars(env, string, isCopy);
5336 }
5337
5338
5339 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
5340                                                                    const jchar *cstring)
5341 {
5342         STATISTICS(jniinvokation());
5343
5344         _Jv_JNI_ReleaseStringChars(env, string, cstring);
5345 }
5346
5347
5348 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
5349 {
5350         STATISTICS(jniinvokation());
5351
5352         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
5353
5354         return obj;
5355 }
5356
5357
5358 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
5359 {
5360         STATISTICS(jniinvokation());
5361
5362         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
5363 }
5364
5365
5366 /* NewGlobalRef ****************************************************************
5367
5368    Creates a new global reference to the object referred to by the obj
5369    argument.
5370
5371 *******************************************************************************/
5372     
5373 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
5374 {
5375         hashtable_global_ref_entry *gre;
5376         u4   key;                           /* hashkey                            */
5377         u4   slot;                          /* slot in hashtable                  */
5378
5379         STATISTICS(jniinvokation());
5380
5381         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5382
5383         /* normally addresses are aligned to 4, 8 or 16 bytes */
5384
5385         key  = ((u4) (ptrint) obj) >> 4;           /* align to 16-byte boundaries */
5386         slot = key & (hashtable_global_ref->size - 1);
5387         gre  = hashtable_global_ref->ptr[slot];
5388         
5389         /* search external hash chain for the entry */
5390
5391         while (gre) {
5392                 if (gre->o == obj) {
5393                         /* global object found, increment the reference */
5394
5395                         gre->refs++;
5396
5397                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5398
5399                         return obj;
5400                 }
5401
5402                 gre = gre->hashlink;                /* next element in external chain */
5403         }
5404
5405         /* global ref not found, create a new one */
5406
5407         gre = NEW(hashtable_global_ref_entry);
5408
5409         gre->o    = obj;
5410         gre->refs = 1;
5411
5412         /* insert entry into hashtable */
5413
5414         gre->hashlink = hashtable_global_ref->ptr[slot];
5415
5416         hashtable_global_ref->ptr[slot] = gre;
5417
5418         /* update number of hashtable-entries */
5419
5420         hashtable_global_ref->entries++;
5421
5422         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5423
5424         return obj;
5425 }
5426
5427
5428 /* DeleteGlobalRef *************************************************************
5429
5430    Deletes the global reference pointed to by globalRef.
5431
5432 *******************************************************************************/
5433
5434 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5435 {
5436         hashtable_global_ref_entry *gre;
5437         hashtable_global_ref_entry *prevgre;
5438         u4   key;                           /* hashkey                            */
5439         u4   slot;                          /* slot in hashtable                  */
5440
5441         STATISTICS(jniinvokation());
5442
5443         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5444
5445         /* normally addresses are aligned to 4, 8 or 16 bytes */
5446
5447         key  = ((u4) (ptrint) globalRef) >> 4;     /* align to 16-byte boundaries */
5448         slot = key & (hashtable_global_ref->size - 1);
5449         gre  = hashtable_global_ref->ptr[slot];
5450
5451         /* initialize prevgre */
5452
5453         prevgre = NULL;
5454
5455         /* search external hash chain for the entry */
5456
5457         while (gre) {
5458                 if (gre->o == globalRef) {
5459                         /* global object found, decrement the reference count */
5460
5461                         gre->refs--;
5462
5463                         /* if reference count is 0, remove the entry */
5464
5465                         if (gre->refs == 0) {
5466                                 /* special handling if it's the first in the chain */
5467
5468                                 if (prevgre == NULL)
5469                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
5470                                 else
5471                                         prevgre->hashlink = gre->hashlink;
5472
5473                                 FREE(gre, hashtable_global_ref_entry);
5474                         }
5475
5476                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5477
5478                         return;
5479                 }
5480
5481                 prevgre = gre;                    /* save current pointer for removal */
5482                 gre     = gre->hashlink;            /* next element in external chain */
5483         }
5484
5485         log_println("JNI-DeleteGlobalRef: global reference not found");
5486
5487         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5488 }
5489
5490
5491 /* ExceptionCheck **************************************************************
5492
5493    Returns JNI_TRUE when there is a pending exception; otherwise,
5494    returns JNI_FALSE.
5495
5496 *******************************************************************************/
5497
5498 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
5499 {
5500         java_objectheader *o;
5501
5502         STATISTICS(jniinvokation());
5503
5504         o = exceptions_get_exception();
5505
5506         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
5507 }
5508
5509
5510 /* New JNI 1.4 functions ******************************************************/
5511
5512 /* NewDirectByteBuffer *********************************************************
5513
5514    Allocates and returns a direct java.nio.ByteBuffer referring to the
5515    block of memory starting at the memory address address and
5516    extending capacity bytes.
5517
5518 *******************************************************************************/
5519
5520 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5521 {
5522 #if defined(ENABLE_JAVASE)
5523         java_objectheader       *nbuf;
5524 # if SIZEOF_VOID_P == 8
5525         gnu_classpath_Pointer64 *paddress;
5526 # else
5527         gnu_classpath_Pointer32 *paddress;
5528 # endif
5529
5530         STATISTICS(jniinvokation());
5531
5532         /* alocate a gnu.classpath.Pointer{32,64} object */
5533
5534 # if SIZEOF_VOID_P == 8
5535         if (!(paddress = (gnu_classpath_Pointer64 *)
5536                   builtin_new(class_gnu_classpath_Pointer64)))
5537 # else
5538         if (!(paddress = (gnu_classpath_Pointer32 *)
5539                   builtin_new(class_gnu_classpath_Pointer32)))
5540 # endif
5541                 return NULL;
5542
5543         /* fill gnu.classpath.Pointer{32,64} with address */
5544
5545         paddress->data = (ptrint) address;
5546
5547         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5548
5549         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5550                                                          (jmethodID) dbbirw_init, NULL, paddress,
5551                                                          (jint) capacity, (jint) capacity, (jint) 0);
5552
5553         /* add local reference and return the value */
5554
5555         return _Jv_JNI_NewLocalRef(env, nbuf);
5556 #else
5557         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
5558
5559         /* keep compiler happy */
5560
5561         return NULL;
5562 #endif
5563 }
5564
5565
5566 /* GetDirectBufferAddress ******************************************************
5567
5568    Fetches and returns the starting address of the memory region
5569    referenced by the given direct java.nio.Buffer.
5570
5571 *******************************************************************************/
5572
5573 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
5574 {
5575 #if defined(ENABLE_JAVASE)
5576         java_nio_DirectByteBufferImpl *nbuf;
5577 # if SIZEOF_VOID_P == 8
5578         gnu_classpath_Pointer64       *address;
5579 # else
5580         gnu_classpath_Pointer32       *address;
5581 # endif
5582
5583         STATISTICS(jniinvokation());
5584
5585         if (!builtin_instanceof(buf, class_java_nio_Buffer))
5586                 return NULL;
5587
5588         nbuf = (java_nio_DirectByteBufferImpl *) buf;
5589
5590 # if SIZEOF_VOID_P == 8
5591         address = (gnu_classpath_Pointer64 *) nbuf->address;
5592 # else
5593         address = (gnu_classpath_Pointer32 *) nbuf->address;
5594 # endif
5595
5596         if (address == NULL)
5597                 return NULL;
5598
5599         return (void *) address->data;
5600 #else
5601         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
5602
5603         /* keep compiler happy */
5604
5605         return NULL;
5606 #endif
5607 }
5608
5609
5610 /* GetDirectBufferCapacity *****************************************************
5611
5612    Fetches and returns the capacity in bytes of the memory region
5613    referenced by the given direct java.nio.Buffer.
5614
5615 *******************************************************************************/
5616
5617 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5618 {
5619 #if defined(ENABLE_JAVASE)
5620         java_nio_Buffer *nbuf;
5621
5622         STATISTICS(jniinvokation());
5623
5624         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5625                 return -1;
5626
5627         nbuf = (java_nio_Buffer *) buf;
5628
5629         return (jlong) nbuf->cap;
5630 #else
5631         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
5632
5633         /* keep compiler happy */
5634
5635         return 0;
5636 #endif
5637 }
5638
5639
5640 /* DestroyJavaVM ***************************************************************
5641
5642    Unloads a Java VM and reclaims its resources. Only the main thread
5643    can unload the VM. The system waits until the main thread is only
5644    remaining user thread before it destroys the VM.
5645
5646 *******************************************************************************/
5647
5648 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
5649 {
5650         s4 status;
5651
5652         STATISTICS(jniinvokation());
5653
5654     status = vm_destroy(vm);
5655
5656         return status;
5657 }
5658
5659
5660 /* AttachCurrentThread *********************************************************
5661
5662    Attaches the current thread to a Java VM. Returns a JNI interface
5663    pointer in the JNIEnv argument.
5664
5665    Trying to attach a thread that is already attached is a no-op.
5666
5667    A native thread cannot be attached simultaneously to two Java VMs.
5668
5669    When a thread is attached to the VM, the context class loader is
5670    the bootstrap loader.
5671
5672 *******************************************************************************/
5673
5674 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
5675 {
5676         JavaVMAttachArgs *vm_aargs;
5677
5678 #if defined(ENABLE_THREADS)
5679         if (threads_get_current_threadobject() == NULL) {
5680                 vm_aargs = (JavaVMAttachArgs *) thr_args;
5681
5682                 if (vm_aargs != NULL) {
5683                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
5684                                 (vm_aargs->version != JNI_VERSION_1_4))
5685                                 return JNI_EVERSION;
5686                 }
5687
5688                 if (!threads_attach_current_thread(vm_aargs, false))
5689                         return JNI_ERR;
5690
5691                 if (!jni_init_localref_table())
5692                         return JNI_ERR;
5693         }
5694 #endif
5695
5696         *p_env = _Jv_env;
5697
5698         return JNI_OK;
5699 }
5700
5701
5702 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
5703 {
5704         STATISTICS(jniinvokation());
5705
5706         return jni_attach_current_thread(p_env, thr_args, false);
5707 }
5708
5709
5710 /* DetachCurrentThread *********************************************************
5711
5712    Detaches the current thread from a Java VM. All Java monitors held
5713    by this thread are released. All Java threads waiting for this
5714    thread to die are notified.
5715
5716    In JDK 1.1, the main thread cannot be detached from the VM. It must
5717    call DestroyJavaVM to unload the entire VM.
5718
5719    In the JDK, the main thread can be detached from the VM.
5720
5721    The main thread, which is the thread that created the Java VM,
5722    cannot be detached from the VM. Instead, the main thread must call
5723    JNI_DestroyJavaVM() to unload the entire VM.
5724
5725 *******************************************************************************/
5726
5727 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
5728 {
5729 #if defined(ENABLE_THREADS)
5730         threadobject *thread;
5731
5732         STATISTICS(jniinvokation());
5733
5734         thread = threads_get_current_threadobject();
5735
5736         if (thread == NULL)
5737                 return JNI_ERR;
5738
5739         if (!jni_free_localref_table())
5740                 return JNI_ERR;
5741
5742         if (!threads_detach_thread(thread))
5743                 return JNI_ERR;
5744 #endif
5745
5746         return JNI_OK;
5747 }
5748
5749
5750 /* GetEnv **********************************************************************
5751
5752    If the current thread is not attached to the VM, sets *env to NULL,
5753    and returns JNI_EDETACHED. If the specified version is not
5754    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5755    sets *env to the appropriate interface, and returns JNI_OK.
5756
5757 *******************************************************************************/
5758
5759 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
5760 {
5761         STATISTICS(jniinvokation());
5762
5763 #if defined(ENABLE_THREADS)
5764         if (threads_get_current_threadobject() == NULL) {
5765                 *env = NULL;
5766
5767                 return JNI_EDETACHED;
5768         }
5769 #endif
5770
5771         /* check the JNI version */
5772
5773         switch (version) {
5774         case JNI_VERSION_1_1:
5775         case JNI_VERSION_1_2:
5776         case JNI_VERSION_1_4:
5777                 *env = _Jv_env;
5778                 return JNI_OK;
5779
5780         default:
5781                 ;
5782         }
5783
5784 #if defined(ENABLE_JVMTI)
5785         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
5786                 == JVMTI_VERSION_INTERFACE_JVMTI) {
5787
5788                 *env = (void *) jvmti_new_environment();
5789
5790                 if (env != NULL)
5791                         return JNI_OK;
5792         }
5793 #endif
5794         
5795         *env = NULL;
5796
5797         return JNI_EVERSION;
5798 }
5799
5800
5801 /* AttachCurrentThreadAsDaemon *************************************************
5802
5803    Same semantics as AttachCurrentThread, but the newly-created
5804    java.lang.Thread instance is a daemon.
5805
5806    If the thread has already been attached via either
5807    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
5808    simply sets the value pointed to by penv to the JNIEnv of the
5809    current thread. In this case neither AttachCurrentThread nor this
5810    routine have any effect on the daemon status of the thread.
5811
5812 *******************************************************************************/
5813
5814 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
5815 {
5816         STATISTICS(jniinvokation());
5817
5818         return jni_attach_current_thread(penv, args, true);
5819 }
5820
5821
5822 /* JNI invocation table *******************************************************/
5823
5824 const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
5825         NULL,
5826         NULL,
5827         NULL,
5828
5829         _Jv_JNI_DestroyJavaVM,
5830         _Jv_JNI_AttachCurrentThread,
5831         _Jv_JNI_DetachCurrentThread,
5832         _Jv_JNI_GetEnv,
5833         _Jv_JNI_AttachCurrentThreadAsDaemon
5834 };
5835
5836
5837 /* JNI function table *********************************************************/
5838
5839 struct JNINativeInterface _Jv_JNINativeInterface = {
5840         NULL,
5841         NULL,
5842         NULL,
5843         NULL,    
5844         _Jv_JNI_GetVersion,
5845
5846         _Jv_JNI_DefineClass,
5847         _Jv_JNI_FindClass,
5848         _Jv_JNI_FromReflectedMethod,
5849         _Jv_JNI_FromReflectedField,
5850         _Jv_JNI_ToReflectedMethod,
5851         _Jv_JNI_GetSuperclass,
5852         _Jv_JNI_IsAssignableFrom,
5853         _Jv_JNI_ToReflectedField,
5854
5855         _Jv_JNI_Throw,
5856         _Jv_JNI_ThrowNew,
5857         _Jv_JNI_ExceptionOccurred,
5858         _Jv_JNI_ExceptionDescribe,
5859         _Jv_JNI_ExceptionClear,
5860         _Jv_JNI_FatalError,
5861         _Jv_JNI_PushLocalFrame,
5862         _Jv_JNI_PopLocalFrame,
5863
5864         _Jv_JNI_NewGlobalRef,
5865         _Jv_JNI_DeleteGlobalRef,
5866         _Jv_JNI_DeleteLocalRef,
5867         _Jv_JNI_IsSameObject,
5868         _Jv_JNI_NewLocalRef,
5869         _Jv_JNI_EnsureLocalCapacity,
5870
5871         _Jv_JNI_AllocObject,
5872         _Jv_JNI_NewObject,
5873         _Jv_JNI_NewObjectV,
5874         _Jv_JNI_NewObjectA,
5875
5876         _Jv_JNI_GetObjectClass,
5877         _Jv_JNI_IsInstanceOf,
5878
5879         _Jv_JNI_GetMethodID,
5880
5881         _Jv_JNI_CallObjectMethod,
5882         _Jv_JNI_CallObjectMethodV,
5883         _Jv_JNI_CallObjectMethodA,
5884         _Jv_JNI_CallBooleanMethod,
5885         _Jv_JNI_CallBooleanMethodV,
5886         _Jv_JNI_CallBooleanMethodA,
5887         _Jv_JNI_CallByteMethod,
5888         _Jv_JNI_CallByteMethodV,
5889         _Jv_JNI_CallByteMethodA,
5890         _Jv_JNI_CallCharMethod,
5891         _Jv_JNI_CallCharMethodV,
5892         _Jv_JNI_CallCharMethodA,
5893         _Jv_JNI_CallShortMethod,
5894         _Jv_JNI_CallShortMethodV,
5895         _Jv_JNI_CallShortMethodA,
5896         _Jv_JNI_CallIntMethod,
5897         _Jv_JNI_CallIntMethodV,
5898         _Jv_JNI_CallIntMethodA,
5899         _Jv_JNI_CallLongMethod,
5900         _Jv_JNI_CallLongMethodV,
5901         _Jv_JNI_CallLongMethodA,
5902         _Jv_JNI_CallFloatMethod,
5903         _Jv_JNI_CallFloatMethodV,
5904         _Jv_JNI_CallFloatMethodA,
5905         _Jv_JNI_CallDoubleMethod,
5906         _Jv_JNI_CallDoubleMethodV,
5907         _Jv_JNI_CallDoubleMethodA,
5908         _Jv_JNI_CallVoidMethod,
5909         _Jv_JNI_CallVoidMethodV,
5910         _Jv_JNI_CallVoidMethodA,
5911
5912         _Jv_JNI_CallNonvirtualObjectMethod,
5913         _Jv_JNI_CallNonvirtualObjectMethodV,
5914         _Jv_JNI_CallNonvirtualObjectMethodA,
5915         _Jv_JNI_CallNonvirtualBooleanMethod,
5916         _Jv_JNI_CallNonvirtualBooleanMethodV,
5917         _Jv_JNI_CallNonvirtualBooleanMethodA,
5918         _Jv_JNI_CallNonvirtualByteMethod,
5919         _Jv_JNI_CallNonvirtualByteMethodV,
5920         _Jv_JNI_CallNonvirtualByteMethodA,
5921         _Jv_JNI_CallNonvirtualCharMethod,
5922         _Jv_JNI_CallNonvirtualCharMethodV,
5923         _Jv_JNI_CallNonvirtualCharMethodA,
5924         _Jv_JNI_CallNonvirtualShortMethod,
5925         _Jv_JNI_CallNonvirtualShortMethodV,
5926         _Jv_JNI_CallNonvirtualShortMethodA,
5927         _Jv_JNI_CallNonvirtualIntMethod,
5928         _Jv_JNI_CallNonvirtualIntMethodV,
5929         _Jv_JNI_CallNonvirtualIntMethodA,
5930         _Jv_JNI_CallNonvirtualLongMethod,
5931         _Jv_JNI_CallNonvirtualLongMethodV,
5932         _Jv_JNI_CallNonvirtualLongMethodA,
5933         _Jv_JNI_CallNonvirtualFloatMethod,
5934         _Jv_JNI_CallNonvirtualFloatMethodV,
5935         _Jv_JNI_CallNonvirtualFloatMethodA,
5936         _Jv_JNI_CallNonvirtualDoubleMethod,
5937         _Jv_JNI_CallNonvirtualDoubleMethodV,
5938         _Jv_JNI_CallNonvirtualDoubleMethodA,
5939         _Jv_JNI_CallNonvirtualVoidMethod,
5940         _Jv_JNI_CallNonvirtualVoidMethodV,
5941         _Jv_JNI_CallNonvirtualVoidMethodA,
5942
5943         _Jv_JNI_GetFieldID,
5944
5945         _Jv_JNI_GetObjectField,
5946         _Jv_JNI_GetBooleanField,
5947         _Jv_JNI_GetByteField,
5948         _Jv_JNI_GetCharField,
5949         _Jv_JNI_GetShortField,
5950         _Jv_JNI_GetIntField,
5951         _Jv_JNI_GetLongField,
5952         _Jv_JNI_GetFloatField,
5953         _Jv_JNI_GetDoubleField,
5954         _Jv_JNI_SetObjectField,
5955         _Jv_JNI_SetBooleanField,
5956         _Jv_JNI_SetByteField,
5957         _Jv_JNI_SetCharField,
5958         _Jv_JNI_SetShortField,
5959         _Jv_JNI_SetIntField,
5960         _Jv_JNI_SetLongField,
5961         _Jv_JNI_SetFloatField,
5962         _Jv_JNI_SetDoubleField,
5963
5964         _Jv_JNI_GetStaticMethodID,
5965
5966         _Jv_JNI_CallStaticObjectMethod,
5967         _Jv_JNI_CallStaticObjectMethodV,
5968         _Jv_JNI_CallStaticObjectMethodA,
5969         _Jv_JNI_CallStaticBooleanMethod,
5970         _Jv_JNI_CallStaticBooleanMethodV,
5971         _Jv_JNI_CallStaticBooleanMethodA,
5972         _Jv_JNI_CallStaticByteMethod,
5973         _Jv_JNI_CallStaticByteMethodV,
5974         _Jv_JNI_CallStaticByteMethodA,
5975         _Jv_JNI_CallStaticCharMethod,
5976         _Jv_JNI_CallStaticCharMethodV,
5977         _Jv_JNI_CallStaticCharMethodA,
5978         _Jv_JNI_CallStaticShortMethod,
5979         _Jv_JNI_CallStaticShortMethodV,
5980         _Jv_JNI_CallStaticShortMethodA,
5981         _Jv_JNI_CallStaticIntMethod,
5982         _Jv_JNI_CallStaticIntMethodV,
5983         _Jv_JNI_CallStaticIntMethodA,
5984         _Jv_JNI_CallStaticLongMethod,
5985         _Jv_JNI_CallStaticLongMethodV,
5986         _Jv_JNI_CallStaticLongMethodA,
5987         _Jv_JNI_CallStaticFloatMethod,
5988         _Jv_JNI_CallStaticFloatMethodV,
5989         _Jv_JNI_CallStaticFloatMethodA,
5990         _Jv_JNI_CallStaticDoubleMethod,
5991         _Jv_JNI_CallStaticDoubleMethodV,
5992         _Jv_JNI_CallStaticDoubleMethodA,
5993         _Jv_JNI_CallStaticVoidMethod,
5994         _Jv_JNI_CallStaticVoidMethodV,
5995         _Jv_JNI_CallStaticVoidMethodA,
5996
5997         _Jv_JNI_GetStaticFieldID,
5998
5999         _Jv_JNI_GetStaticObjectField,
6000         _Jv_JNI_GetStaticBooleanField,
6001         _Jv_JNI_GetStaticByteField,
6002         _Jv_JNI_GetStaticCharField,
6003         _Jv_JNI_GetStaticShortField,
6004         _Jv_JNI_GetStaticIntField,
6005         _Jv_JNI_GetStaticLongField,
6006         _Jv_JNI_GetStaticFloatField,
6007         _Jv_JNI_GetStaticDoubleField,
6008         _Jv_JNI_SetStaticObjectField,
6009         _Jv_JNI_SetStaticBooleanField,
6010         _Jv_JNI_SetStaticByteField,
6011         _Jv_JNI_SetStaticCharField,
6012         _Jv_JNI_SetStaticShortField,
6013         _Jv_JNI_SetStaticIntField,
6014         _Jv_JNI_SetStaticLongField,
6015         _Jv_JNI_SetStaticFloatField,
6016         _Jv_JNI_SetStaticDoubleField,
6017
6018         _Jv_JNI_NewString,
6019         _Jv_JNI_GetStringLength,
6020         _Jv_JNI_GetStringChars,
6021         _Jv_JNI_ReleaseStringChars,
6022
6023         _Jv_JNI_NewStringUTF,
6024         _Jv_JNI_GetStringUTFLength,
6025         _Jv_JNI_GetStringUTFChars,
6026         _Jv_JNI_ReleaseStringUTFChars,
6027
6028         _Jv_JNI_GetArrayLength,
6029
6030         _Jv_JNI_NewObjectArray,
6031         _Jv_JNI_GetObjectArrayElement,
6032         _Jv_JNI_SetObjectArrayElement,
6033
6034         _Jv_JNI_NewBooleanArray,
6035         _Jv_JNI_NewByteArray,
6036         _Jv_JNI_NewCharArray,
6037         _Jv_JNI_NewShortArray,
6038         _Jv_JNI_NewIntArray,
6039         _Jv_JNI_NewLongArray,
6040         _Jv_JNI_NewFloatArray,
6041         _Jv_JNI_NewDoubleArray,
6042
6043         _Jv_JNI_GetBooleanArrayElements,
6044         _Jv_JNI_GetByteArrayElements,
6045         _Jv_JNI_GetCharArrayElements,
6046         _Jv_JNI_GetShortArrayElements,
6047         _Jv_JNI_GetIntArrayElements,
6048         _Jv_JNI_GetLongArrayElements,
6049         _Jv_JNI_GetFloatArrayElements,
6050         _Jv_JNI_GetDoubleArrayElements,
6051
6052         _Jv_JNI_ReleaseBooleanArrayElements,
6053         _Jv_JNI_ReleaseByteArrayElements,
6054         _Jv_JNI_ReleaseCharArrayElements,
6055         _Jv_JNI_ReleaseShortArrayElements,
6056         _Jv_JNI_ReleaseIntArrayElements,
6057         _Jv_JNI_ReleaseLongArrayElements,
6058         _Jv_JNI_ReleaseFloatArrayElements,
6059         _Jv_JNI_ReleaseDoubleArrayElements,
6060
6061         _Jv_JNI_GetBooleanArrayRegion,
6062         _Jv_JNI_GetByteArrayRegion,
6063         _Jv_JNI_GetCharArrayRegion,
6064         _Jv_JNI_GetShortArrayRegion,
6065         _Jv_JNI_GetIntArrayRegion,
6066         _Jv_JNI_GetLongArrayRegion,
6067         _Jv_JNI_GetFloatArrayRegion,
6068         _Jv_JNI_GetDoubleArrayRegion,
6069         _Jv_JNI_SetBooleanArrayRegion,
6070         _Jv_JNI_SetByteArrayRegion,
6071         _Jv_JNI_SetCharArrayRegion,
6072         _Jv_JNI_SetShortArrayRegion,
6073         _Jv_JNI_SetIntArrayRegion,
6074         _Jv_JNI_SetLongArrayRegion,
6075         _Jv_JNI_SetFloatArrayRegion,
6076         _Jv_JNI_SetDoubleArrayRegion,
6077
6078         _Jv_JNI_RegisterNatives,
6079         _Jv_JNI_UnregisterNatives,
6080
6081         _Jv_JNI_MonitorEnter,
6082         _Jv_JNI_MonitorExit,
6083
6084         _Jv_JNI_GetJavaVM,
6085
6086         /* new JNI 1.2 functions */
6087
6088         _Jv_JNI_GetStringRegion,
6089         _Jv_JNI_GetStringUTFRegion,
6090
6091         _Jv_JNI_GetPrimitiveArrayCritical,
6092         _Jv_JNI_ReleasePrimitiveArrayCritical,
6093
6094         _Jv_JNI_GetStringCritical,
6095         _Jv_JNI_ReleaseStringCritical,
6096
6097         _Jv_JNI_NewWeakGlobalRef,
6098         _Jv_JNI_DeleteWeakGlobalRef,
6099
6100         _Jv_JNI_ExceptionCheck,
6101
6102         /* new JNI 1.4 functions */
6103
6104         _Jv_JNI_NewDirectByteBuffer,
6105         _Jv_JNI_GetDirectBufferAddress,
6106         _Jv_JNI_GetDirectBufferCapacity
6107 };
6108
6109
6110 /* Invocation API Functions ***************************************************/
6111
6112 /* JNI_GetDefaultJavaVMInitArgs ************************************************
6113
6114    Returns a default configuration for the Java VM.
6115
6116 *******************************************************************************/
6117
6118 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
6119 {
6120         JavaVMInitArgs *_vm_args;
6121
6122         _vm_args = (JavaVMInitArgs *) vm_args;
6123
6124         /* GNU classpath currently supports JNI 1.2 */
6125
6126         switch (_vm_args->version) {
6127     case JNI_VERSION_1_1:
6128                 _vm_args->version = JNI_VERSION_1_1;
6129                 break;
6130
6131     case JNI_VERSION_1_2:
6132     case JNI_VERSION_1_4:
6133                 _vm_args->ignoreUnrecognized = JNI_FALSE;
6134                 _vm_args->options = NULL;
6135                 _vm_args->nOptions = 0;
6136                 break;
6137
6138     default:
6139                 return -1;
6140         }
6141   
6142         return 0;
6143 }
6144
6145
6146 /* JNI_GetCreatedJavaVMs *******************************************************
6147
6148    Returns all Java VMs that have been created. Pointers to VMs are written in
6149    the buffer vmBuf in the order they are created. At most bufLen number of
6150    entries will be written. The total number of created VMs is returned in
6151    *nVMs.
6152
6153 *******************************************************************************/
6154
6155 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
6156 {
6157         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
6158
6159         return 0;
6160 }
6161
6162
6163 /* JNI_CreateJavaVM ************************************************************
6164
6165    Loads and initializes a Java VM. The current thread becomes the main thread.
6166    Sets the env argument to the JNI interface pointer of the main thread.
6167
6168 *******************************************************************************/
6169
6170 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
6171 {
6172         /* actually create the JVM */
6173
6174         if (!vm_createjvm(p_vm, p_env, vm_args))
6175                 return JNI_ERR;
6176
6177         return JNI_OK;
6178 }
6179
6180
6181 /*
6182  * These are local overrides for various environment variables in Emacs.
6183  * Please do not remove this and leave it at the end of the file, where
6184  * Emacs will automagically detect them.
6185  * ---------------------------------------------------------------------
6186  * Local variables:
6187  * mode: c
6188  * indent-tabs-mode: t
6189  * c-basic-offset: 4
6190  * tab-width: 4
6191  * End:
6192  * vim:noexpandtab:sw=4:ts=4:
6193  */