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