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