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