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