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