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