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