* src/native/jni.c (_Jv_jni_invokeNative): Release memory in exception
[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 7526 2007-03-15 09:28:56Z 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                 exceptions_throw_arraystoreexception();
4306                 return;
4307         }
4308
4309         oa->data[index] = val;
4310 }
4311
4312
4313 jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
4314 {
4315         java_booleanarray *ba;
4316
4317         STATISTICS(jniinvokation());
4318
4319         if (len < 0) {
4320                 exceptions_throw_negativearraysizeexception();
4321                 return NULL;
4322         }
4323
4324         ba = builtin_newarray_boolean(len);
4325
4326         return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4327 }
4328
4329
4330 jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
4331 {
4332         java_bytearray *ba;
4333
4334         STATISTICS(jniinvokation());
4335
4336         if (len < 0) {
4337                 exceptions_throw_negativearraysizeexception();
4338                 return NULL;
4339         }
4340
4341         ba = builtin_newarray_byte(len);
4342
4343         return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
4344 }
4345
4346
4347 jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
4348 {
4349         java_chararray *ca;
4350
4351         STATISTICS(jniinvokation());
4352
4353         if (len < 0) {
4354                 exceptions_throw_negativearraysizeexception();
4355                 return NULL;
4356         }
4357
4358         ca = builtin_newarray_char(len);
4359
4360         return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
4361 }
4362
4363
4364 jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
4365 {
4366         java_shortarray *sa;
4367
4368         STATISTICS(jniinvokation());
4369
4370         if (len < 0) {
4371                 exceptions_throw_negativearraysizeexception();
4372                 return NULL;
4373         }
4374
4375         sa = builtin_newarray_short(len);
4376
4377         return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
4378 }
4379
4380
4381 jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
4382 {
4383         java_intarray *ia;
4384
4385         STATISTICS(jniinvokation());
4386
4387         if (len < 0) {
4388                 exceptions_throw_negativearraysizeexception();
4389                 return NULL;
4390         }
4391
4392         ia = builtin_newarray_int(len);
4393
4394         return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
4395 }
4396
4397
4398 jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
4399 {
4400         java_longarray *la;
4401
4402         STATISTICS(jniinvokation());
4403
4404         if (len < 0) {
4405                 exceptions_throw_negativearraysizeexception();
4406                 return NULL;
4407         }
4408
4409         la = builtin_newarray_long(len);
4410
4411         return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
4412 }
4413
4414
4415 jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
4416 {
4417         java_floatarray *fa;
4418
4419         STATISTICS(jniinvokation());
4420
4421         if (len < 0) {
4422                 exceptions_throw_negativearraysizeexception();
4423                 return NULL;
4424         }
4425
4426         fa = builtin_newarray_float(len);
4427
4428         return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
4429 }
4430
4431
4432 jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
4433 {
4434         java_doublearray *da;
4435
4436         STATISTICS(jniinvokation());
4437
4438         if (len < 0) {
4439                 exceptions_throw_negativearraysizeexception();
4440                 return NULL;
4441         }
4442
4443         da = builtin_newarray_double(len);
4444
4445         return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
4446 }
4447
4448
4449 /* Get<PrimitiveType>ArrayElements *********************************************
4450
4451    A family of functions that returns the body of the primitive array.
4452
4453 *******************************************************************************/
4454
4455 jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4456                                                                                   jboolean *isCopy)
4457 {
4458         java_booleanarray *ba;
4459
4460         STATISTICS(jniinvokation());
4461
4462         ba = (java_booleanarray *) array;
4463
4464         if (isCopy)
4465                 *isCopy = JNI_FALSE;
4466
4467         return ba->data;
4468 }
4469
4470
4471 jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
4472                                                                         jboolean *isCopy)
4473 {
4474         java_bytearray *ba;
4475
4476         STATISTICS(jniinvokation());
4477
4478         ba = (java_bytearray *) array;
4479
4480         if (isCopy)
4481                 *isCopy = JNI_FALSE;
4482
4483         return ba->data;
4484 }
4485
4486
4487 jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
4488                                                                         jboolean *isCopy)
4489 {
4490         java_chararray *ca;
4491
4492         STATISTICS(jniinvokation());
4493
4494         ca = (java_chararray *) array;
4495
4496         if (isCopy)
4497                 *isCopy = JNI_FALSE;
4498
4499         return ca->data;
4500 }
4501
4502
4503 jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
4504                                                                           jboolean *isCopy)
4505 {
4506         java_shortarray *sa;
4507
4508         STATISTICS(jniinvokation());
4509
4510         sa = (java_shortarray *) array;
4511
4512         if (isCopy)
4513                 *isCopy = JNI_FALSE;
4514
4515         return sa->data;
4516 }
4517
4518
4519 jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
4520                                                                   jboolean *isCopy)
4521 {
4522         java_intarray *ia;
4523
4524         STATISTICS(jniinvokation());
4525
4526         ia = (java_intarray *) array;
4527
4528         if (isCopy)
4529                 *isCopy = JNI_FALSE;
4530
4531         return ia->data;
4532 }
4533
4534
4535 jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
4536                                                                         jboolean *isCopy)
4537 {
4538         java_longarray *la;
4539
4540         STATISTICS(jniinvokation());
4541
4542         la = (java_longarray *) array;
4543
4544         if (isCopy)
4545                 *isCopy = JNI_FALSE;
4546
4547         /* We cast this one to prevent a compiler warning on 64-bit
4548            systems since GNU Classpath typedef jlong to long long. */
4549
4550         return (jlong *) la->data;
4551 }
4552
4553
4554 jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
4555                                                                           jboolean *isCopy)
4556 {
4557         java_floatarray *fa;
4558
4559         STATISTICS(jniinvokation());
4560
4561         fa = (java_floatarray *) array;
4562
4563         if (isCopy)
4564                 *isCopy = JNI_FALSE;
4565
4566         return fa->data;
4567 }
4568
4569
4570 jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4571                                                                                 jboolean *isCopy)
4572 {
4573         java_doublearray *da;
4574
4575         STATISTICS(jniinvokation());
4576
4577         da = (java_doublearray *) array;
4578
4579         if (isCopy)
4580                 *isCopy = JNI_FALSE;
4581
4582         return da->data;
4583 }
4584
4585
4586 /* Release<PrimitiveType>ArrayElements *****************************************
4587
4588    A family of functions that informs the VM that the native code no
4589    longer needs access to elems. The elems argument is a pointer
4590    derived from array using the corresponding
4591    Get<PrimitiveType>ArrayElements() function. If necessary, this
4592    function copies back all changes made to elems to the original
4593    array.
4594
4595 *******************************************************************************/
4596
4597 void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
4598                                                                                  jboolean *elems, jint mode)
4599 {
4600         java_booleanarray *ba;
4601
4602         STATISTICS(jniinvokation());
4603
4604         ba = (java_booleanarray *) array;
4605
4606         if (elems != ba->data) {
4607                 switch (mode) {
4608                 case JNI_COMMIT:
4609                         MCOPY(ba->data, elems, u1, ba->header.size);
4610                         break;
4611                 case 0:
4612                         MCOPY(ba->data, elems, u1, ba->header.size);
4613                         /* XXX TWISTI how should it be freed? */
4614                         break;
4615                 case JNI_ABORT:
4616                         /* XXX TWISTI how should it be freed? */
4617                         break;
4618                 }
4619         }
4620 }
4621
4622
4623 void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
4624                                                                           jbyte *elems, jint mode)
4625 {
4626         java_bytearray *ba;
4627
4628         STATISTICS(jniinvokation());
4629
4630         ba = (java_bytearray *) array;
4631
4632         if (elems != ba->data) {
4633                 switch (mode) {
4634                 case JNI_COMMIT:
4635                         MCOPY(ba->data, elems, s1, ba->header.size);
4636                         break;
4637                 case 0:
4638                         MCOPY(ba->data, elems, s1, ba->header.size);
4639                         /* XXX TWISTI how should it be freed? */
4640                         break;
4641                 case JNI_ABORT:
4642                         /* XXX TWISTI how should it be freed? */
4643                         break;
4644                 }
4645         }
4646 }
4647
4648
4649 void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
4650                                                                           jchar *elems, jint mode)
4651 {
4652         java_chararray *ca;
4653
4654         STATISTICS(jniinvokation());
4655
4656         ca = (java_chararray *) array;
4657
4658         if (elems != ca->data) {
4659                 switch (mode) {
4660                 case JNI_COMMIT:
4661                         MCOPY(ca->data, elems, u2, ca->header.size);
4662                         break;
4663                 case 0:
4664                         MCOPY(ca->data, elems, u2, ca->header.size);
4665                         /* XXX TWISTI how should it be freed? */
4666                         break;
4667                 case JNI_ABORT:
4668                         /* XXX TWISTI how should it be freed? */
4669                         break;
4670                 }
4671         }
4672 }
4673
4674
4675 void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
4676                                                                            jshort *elems, jint mode)
4677 {
4678         java_shortarray *sa;
4679
4680         STATISTICS(jniinvokation());
4681
4682         sa = (java_shortarray *) array;
4683
4684         if (elems != sa->data) {
4685                 switch (mode) {
4686                 case JNI_COMMIT:
4687                         MCOPY(sa->data, elems, s2, sa->header.size);
4688                         break;
4689                 case 0:
4690                         MCOPY(sa->data, elems, s2, sa->header.size);
4691                         /* XXX TWISTI how should it be freed? */
4692                         break;
4693                 case JNI_ABORT:
4694                         /* XXX TWISTI how should it be freed? */
4695                         break;
4696                 }
4697         }
4698 }
4699
4700
4701 void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
4702                                                                          jint mode)
4703 {
4704         java_intarray *ia;
4705
4706         STATISTICS(jniinvokation());
4707
4708         ia = (java_intarray *) array;
4709
4710         if (elems != ia->data) {
4711                 switch (mode) {
4712                 case JNI_COMMIT:
4713                         MCOPY(ia->data, elems, s4, ia->header.size);
4714                         break;
4715                 case 0:
4716                         MCOPY(ia->data, elems, s4, ia->header.size);
4717                         /* XXX TWISTI how should it be freed? */
4718                         break;
4719                 case JNI_ABORT:
4720                         /* XXX TWISTI how should it be freed? */
4721                         break;
4722                 }
4723         }
4724 }
4725
4726
4727 void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
4728                                                                           jlong *elems, jint mode)
4729 {
4730         java_longarray *la;
4731
4732         STATISTICS(jniinvokation());
4733
4734         la = (java_longarray *) array;
4735
4736         /* We cast this one to prevent a compiler warning on 64-bit
4737            systems since GNU Classpath typedef jlong to long long. */
4738
4739         if ((s8 *) elems != la->data) {
4740                 switch (mode) {
4741                 case JNI_COMMIT:
4742                         MCOPY(la->data, elems, s8, la->header.size);
4743                         break;
4744                 case 0:
4745                         MCOPY(la->data, elems, s8, la->header.size);
4746                         /* XXX TWISTI how should it be freed? */
4747                         break;
4748                 case JNI_ABORT:
4749                         /* XXX TWISTI how should it be freed? */
4750                         break;
4751                 }
4752         }
4753 }
4754
4755
4756 void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
4757                                                                            jfloat *elems, jint mode)
4758 {
4759         java_floatarray *fa;
4760
4761         STATISTICS(jniinvokation());
4762
4763         fa = (java_floatarray *) array;
4764
4765         if (elems != fa->data) {
4766                 switch (mode) {
4767                 case JNI_COMMIT:
4768                         MCOPY(fa->data, elems, float, fa->header.size);
4769                         break;
4770                 case 0:
4771                         MCOPY(fa->data, elems, float, fa->header.size);
4772                         /* XXX TWISTI how should it be freed? */
4773                         break;
4774                 case JNI_ABORT:
4775                         /* XXX TWISTI how should it be freed? */
4776                         break;
4777                 }
4778         }
4779 }
4780
4781
4782 void _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
4783                                                                                 jdouble *elems, jint mode)
4784 {
4785         java_doublearray *da;
4786
4787         STATISTICS(jniinvokation());
4788
4789         da = (java_doublearray *) array;
4790
4791         if (elems != da->data) {
4792                 switch (mode) {
4793                 case JNI_COMMIT:
4794                         MCOPY(da->data, elems, double, da->header.size);
4795                         break;
4796                 case 0:
4797                         MCOPY(da->data, elems, double, da->header.size);
4798                         /* XXX TWISTI how should it be freed? */
4799                         break;
4800                 case JNI_ABORT:
4801                         /* XXX TWISTI how should it be freed? */
4802                         break;
4803                 }
4804         }
4805 }
4806
4807
4808 /*  Get<PrimitiveType>ArrayRegion **********************************************
4809
4810         A family of functions that copies a region of a primitive array
4811         into a buffer.
4812
4813 *******************************************************************************/
4814
4815 void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
4816                                                                    jsize start, jsize len, jboolean *buf)
4817 {
4818         java_booleanarray *ba;
4819
4820         STATISTICS(jniinvokation());
4821
4822         ba = (java_booleanarray *) array;
4823
4824     if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4825                 exceptions_throw_arrayindexoutofboundsexception();
4826     else
4827                 MCOPY(buf, &ba->data[start], u1, len);
4828 }
4829
4830
4831 void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
4832                                                                 jsize len, jbyte *buf)
4833 {
4834         java_bytearray *ba;
4835
4836         STATISTICS(jniinvokation());
4837
4838         ba = (java_bytearray *) array;
4839
4840         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4841                 exceptions_throw_arrayindexoutofboundsexception();
4842         else
4843                 MCOPY(buf, &ba->data[start], s1, len);
4844 }
4845
4846
4847 void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
4848                                                                 jsize len, jchar *buf)
4849 {
4850         java_chararray *ca;
4851
4852         STATISTICS(jniinvokation());
4853
4854         ca = (java_chararray *) array;
4855
4856         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4857                 exceptions_throw_arrayindexoutofboundsexception();
4858         else
4859                 MCOPY(buf, &ca->data[start], u2, len);
4860 }
4861
4862
4863 void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4864                                                                  jsize len, jshort *buf)
4865 {
4866         java_shortarray *sa;
4867
4868         STATISTICS(jniinvokation());
4869
4870         sa = (java_shortarray *) array;
4871
4872         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
4873                 exceptions_throw_arrayindexoutofboundsexception();
4874         else    
4875                 MCOPY(buf, &sa->data[start], s2, len);
4876 }
4877
4878
4879 void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
4880                                                            jsize len, jint *buf)
4881 {
4882         java_intarray *ia;
4883
4884         STATISTICS(jniinvokation());
4885
4886         ia = (java_intarray *) array;
4887
4888         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
4889                 exceptions_throw_arrayindexoutofboundsexception();
4890         else
4891                 MCOPY(buf, &ia->data[start], s4, len);
4892 }
4893
4894
4895 void _Jv_JNI_GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start,
4896                                                                 jsize len, jlong *buf)
4897 {
4898         java_longarray *la;
4899
4900         STATISTICS(jniinvokation());
4901
4902         la = (java_longarray *) array;
4903
4904         if ((start < 0) || (len < 0) || (start + len > la->header.size))
4905                 exceptions_throw_arrayindexoutofboundsexception();
4906         else
4907                 MCOPY(buf, &la->data[start], s8, len);
4908 }
4909
4910
4911 void _Jv_JNI_GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
4912                                                                  jsize len, jfloat *buf)
4913 {
4914         java_floatarray *fa;
4915
4916         STATISTICS(jniinvokation());
4917
4918         fa = (java_floatarray *) array;
4919
4920         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
4921                 exceptions_throw_arrayindexoutofboundsexception();
4922         else
4923                 MCOPY(buf, &fa->data[start], float, len);
4924 }
4925
4926
4927 void _Jv_JNI_GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4928                                                                   jsize len, jdouble *buf)
4929 {
4930         java_doublearray *da;
4931
4932         STATISTICS(jniinvokation());
4933
4934         da = (java_doublearray *) array;
4935
4936         if ((start < 0) || (len < 0) || (start + len > da->header.size))
4937                 exceptions_throw_arrayindexoutofboundsexception();
4938         else
4939                 MCOPY(buf, &da->data[start], double, len);
4940 }
4941
4942
4943 /*  Set<PrimitiveType>ArrayRegion **********************************************
4944
4945         A family of functions that copies back a region of a primitive
4946         array from a buffer.
4947
4948 *******************************************************************************/
4949
4950 void _Jv_JNI_SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
4951                                                                    jsize start, jsize len, jboolean *buf)
4952 {
4953         java_booleanarray *ba;
4954
4955         STATISTICS(jniinvokation());
4956
4957         ba = (java_booleanarray *) array;
4958
4959         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4960                 exceptions_throw_arrayindexoutofboundsexception();
4961         else
4962                 MCOPY(&ba->data[start], buf, u1, len);
4963 }
4964
4965
4966 void _Jv_JNI_SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
4967                                                                 jsize len, jbyte *buf)
4968 {
4969         java_bytearray *ba;
4970
4971         STATISTICS(jniinvokation());
4972
4973         ba = (java_bytearray *) array;
4974
4975         if ((start < 0) || (len < 0) || (start + len > ba->header.size))
4976                 exceptions_throw_arrayindexoutofboundsexception();
4977         else
4978                 MCOPY(&ba->data[start], buf, s1, len);
4979 }
4980
4981
4982 void _Jv_JNI_SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
4983                                                                 jsize len, jchar *buf)
4984 {
4985         java_chararray *ca;
4986
4987         STATISTICS(jniinvokation());
4988
4989         ca = (java_chararray *) array;
4990
4991         if ((start < 0) || (len < 0) || (start + len > ca->header.size))
4992                 exceptions_throw_arrayindexoutofboundsexception();
4993         else
4994                 MCOPY(&ca->data[start], buf, u2, len);
4995 }
4996
4997
4998 void _Jv_JNI_SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
4999                                                                  jsize len, jshort *buf)
5000 {
5001         java_shortarray *sa;
5002
5003         STATISTICS(jniinvokation());
5004
5005         sa = (java_shortarray *) array;
5006
5007         if ((start < 0) || (len < 0) || (start + len > sa->header.size))
5008                 exceptions_throw_arrayindexoutofboundsexception();
5009         else
5010                 MCOPY(&sa->data[start], buf, s2, len);
5011 }
5012
5013
5014 void _Jv_JNI_SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
5015                                                            jsize len, jint *buf)
5016 {
5017         java_intarray *ia;
5018
5019         STATISTICS(jniinvokation());
5020
5021         ia = (java_intarray *) array;
5022
5023         if ((start < 0) || (len < 0) || (start + len > ia->header.size))
5024                 exceptions_throw_arrayindexoutofboundsexception();
5025         else
5026                 MCOPY(&ia->data[start], buf, s4, len);
5027 }
5028
5029
5030 void _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
5031                                                                 jsize len, jlong *buf)
5032 {
5033         java_longarray *la;
5034
5035         STATISTICS(jniinvokation());
5036
5037         la = (java_longarray *) array;
5038
5039         if ((start < 0) || (len < 0) || (start + len > la->header.size))
5040                 exceptions_throw_arrayindexoutofboundsexception();
5041         else
5042                 MCOPY(&la->data[start], buf, s8, len);
5043 }
5044
5045
5046 void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
5047                                                                  jsize len, jfloat *buf)
5048 {
5049         java_floatarray *fa;
5050
5051         STATISTICS(jniinvokation());
5052
5053         fa = (java_floatarray *) array;
5054
5055         if ((start < 0) || (len < 0) || (start + len > fa->header.size))
5056                 exceptions_throw_arrayindexoutofboundsexception();
5057         else
5058                 MCOPY(&fa->data[start], buf, float, len);
5059 }
5060
5061
5062 void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
5063                                                                   jsize len, jdouble *buf)
5064 {
5065         java_doublearray *da;
5066
5067         STATISTICS(jniinvokation());
5068
5069         da = (java_doublearray *) array;
5070
5071         if ((start < 0) || (len < 0) || (start + len > da->header.size))
5072                 exceptions_throw_arrayindexoutofboundsexception();
5073         else
5074                 MCOPY(&da->data[start], buf, double, len);
5075 }
5076
5077
5078 /* Registering Native Methods *************************************************/
5079
5080 /* RegisterNatives *************************************************************
5081
5082    Registers native methods with the class specified by the clazz
5083    argument. The methods parameter specifies an array of
5084    JNINativeMethod structures that contain the names, signatures, and
5085    function pointers of the native methods. The nMethods parameter
5086    specifies the number of native methods in the array.
5087
5088 *******************************************************************************/
5089
5090 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
5091                                                          const JNINativeMethod *methods, jint nMethods)
5092 {
5093         STATISTICS(jniinvokation());
5094
5095     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
5096         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
5097         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
5098         */
5099
5100     return 0;
5101 }
5102
5103
5104 /* UnregisterNatives ***********************************************************
5105
5106    Unregisters native methods of a class. The class goes back to the
5107    state before it was linked or registered with its native method
5108    functions.
5109
5110    This function should not be used in normal native code. Instead, it
5111    provides special programs a way to reload and relink native
5112    libraries.
5113
5114 *******************************************************************************/
5115
5116 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
5117 {
5118         STATISTICS(jniinvokation());
5119
5120         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
5121
5122     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
5123
5124     return 0;
5125 }
5126
5127
5128 /* Monitor Operations *********************************************************/
5129
5130 /* MonitorEnter ****************************************************************
5131
5132    Enters the monitor associated with the underlying Java object
5133    referred to by obj.
5134
5135 *******************************************************************************/
5136
5137 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
5138 {
5139         STATISTICS(jniinvokation());
5140
5141         if (obj == NULL) {
5142                 exceptions_throw_nullpointerexception();
5143                 return JNI_ERR;
5144         }
5145
5146         LOCK_MONITOR_ENTER(obj);
5147
5148         return JNI_OK;
5149 }
5150
5151
5152 /* MonitorExit *****************************************************************
5153
5154    The current thread must be the owner of the monitor associated with
5155    the underlying Java object referred to by obj. The thread
5156    decrements the counter indicating the number of times it has
5157    entered this monitor. If the value of the counter becomes zero, the
5158    current thread releases the monitor.
5159
5160 *******************************************************************************/
5161
5162 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
5163 {
5164         STATISTICS(jniinvokation());
5165
5166         if (obj == NULL) {
5167                 exceptions_throw_nullpointerexception();
5168                 return JNI_ERR;
5169         }
5170
5171         LOCK_MONITOR_EXIT(obj);
5172
5173         return JNI_OK;
5174 }
5175
5176
5177 /* JavaVM Interface ***********************************************************/
5178
5179 /* GetJavaVM *******************************************************************
5180
5181    Returns the Java VM interface (used in the Invocation API)
5182    associated with the current thread. The result is placed at the
5183    location pointed to by the second argument, vm.
5184
5185 *******************************************************************************/
5186
5187 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
5188 {
5189         STATISTICS(jniinvokation());
5190
5191     *vm = (JavaVM *) _Jv_jvm;
5192
5193         return 0;
5194 }
5195
5196
5197 /* GetStringRegion *************************************************************
5198
5199    Copies len number of Unicode characters beginning at offset start
5200    to the given buffer buf.
5201
5202    Throws StringIndexOutOfBoundsException on index overflow.
5203
5204 *******************************************************************************/
5205
5206 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
5207                                                          jchar *buf)
5208 {
5209         java_lang_String *s;
5210         java_chararray   *ca;
5211
5212         STATISTICS(jniinvokation());
5213
5214         s  = (java_lang_String *) str;
5215         ca = s->value;
5216
5217         if ((start < 0) || (len < 0) || (start > s->count) ||
5218                 (start + len > s->count)) {
5219                 exceptions_throw_stringindexoutofboundsexception();
5220                 return;
5221         }
5222
5223         MCOPY(buf, &ca->data[start], u2, len);
5224 }
5225
5226
5227 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
5228                                                                 jsize len, char *buf)
5229 {
5230         STATISTICS(jniinvokation());
5231
5232         log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
5233 }
5234
5235
5236 /* GetPrimitiveArrayCritical ***************************************************
5237
5238    Obtain a direct pointer to array elements.
5239
5240 *******************************************************************************/
5241
5242 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
5243                                                                                 jboolean *isCopy)
5244 {
5245         java_bytearray *ba;
5246         jbyte          *bp;
5247
5248         ba = (java_bytearray *) array;
5249
5250         /* do the same as Kaffe does */
5251
5252         bp = _Jv_JNI_GetByteArrayElements(env, ba, isCopy);
5253
5254         return (void *) bp;
5255 }
5256
5257
5258 /* ReleasePrimitiveArrayCritical ***********************************************
5259
5260    No specific documentation.
5261
5262 *******************************************************************************/
5263
5264 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
5265                                                                                    void *carray, jint mode)
5266 {
5267         STATISTICS(jniinvokation());
5268
5269         /* do the same as Kaffe does */
5270
5271         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
5272                                                                          mode);
5273 }
5274
5275
5276 /* GetStringCritical ***********************************************************
5277
5278    The semantics of these two functions are similar to the existing
5279    Get/ReleaseStringChars functions.
5280
5281 *******************************************************************************/
5282
5283 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
5284                                                                            jboolean *isCopy)
5285 {
5286         STATISTICS(jniinvokation());
5287
5288         return _Jv_JNI_GetStringChars(env, string, isCopy);
5289 }
5290
5291
5292 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
5293                                                                    const jchar *cstring)
5294 {
5295         STATISTICS(jniinvokation());
5296
5297         _Jv_JNI_ReleaseStringChars(env, string, cstring);
5298 }
5299
5300
5301 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
5302 {
5303         STATISTICS(jniinvokation());
5304
5305         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
5306
5307         return obj;
5308 }
5309
5310
5311 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
5312 {
5313         STATISTICS(jniinvokation());
5314
5315         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
5316 }
5317
5318
5319 /* NewGlobalRef ****************************************************************
5320
5321    Creates a new global reference to the object referred to by the obj
5322    argument.
5323
5324 *******************************************************************************/
5325     
5326 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
5327 {
5328         hashtable_global_ref_entry *gre;
5329         u4   key;                           /* hashkey                            */
5330         u4   slot;                          /* slot in hashtable                  */
5331
5332         STATISTICS(jniinvokation());
5333
5334         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5335
5336         /* normally addresses are aligned to 4, 8 or 16 bytes */
5337
5338         key  = ((u4) (ptrint) obj) >> 4;           /* align to 16-byte boundaries */
5339         slot = key & (hashtable_global_ref->size - 1);
5340         gre  = hashtable_global_ref->ptr[slot];
5341         
5342         /* search external hash chain for the entry */
5343
5344         while (gre) {
5345                 if (gre->o == obj) {
5346                         /* global object found, increment the reference */
5347
5348                         gre->refs++;
5349
5350                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5351
5352                         return obj;
5353                 }
5354
5355                 gre = gre->hashlink;                /* next element in external chain */
5356         }
5357
5358         /* global ref not found, create a new one */
5359
5360         gre = NEW(hashtable_global_ref_entry);
5361
5362         gre->o    = obj;
5363         gre->refs = 1;
5364
5365         /* insert entry into hashtable */
5366
5367         gre->hashlink = hashtable_global_ref->ptr[slot];
5368
5369         hashtable_global_ref->ptr[slot] = gre;
5370
5371         /* update number of hashtable-entries */
5372
5373         hashtable_global_ref->entries++;
5374
5375         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5376
5377         return obj;
5378 }
5379
5380
5381 /* DeleteGlobalRef *************************************************************
5382
5383    Deletes the global reference pointed to by globalRef.
5384
5385 *******************************************************************************/
5386
5387 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
5388 {
5389         hashtable_global_ref_entry *gre;
5390         hashtable_global_ref_entry *prevgre;
5391         u4   key;                           /* hashkey                            */
5392         u4   slot;                          /* slot in hashtable                  */
5393
5394         STATISTICS(jniinvokation());
5395
5396         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
5397
5398         /* normally addresses are aligned to 4, 8 or 16 bytes */
5399
5400         key  = ((u4) (ptrint) globalRef) >> 4;     /* align to 16-byte boundaries */
5401         slot = key & (hashtable_global_ref->size - 1);
5402         gre  = hashtable_global_ref->ptr[slot];
5403
5404         /* initialize prevgre */
5405
5406         prevgre = NULL;
5407
5408         /* search external hash chain for the entry */
5409
5410         while (gre) {
5411                 if (gre->o == globalRef) {
5412                         /* global object found, decrement the reference count */
5413
5414                         gre->refs--;
5415
5416                         /* if reference count is 0, remove the entry */
5417
5418                         if (gre->refs == 0) {
5419                                 /* special handling if it's the first in the chain */
5420
5421                                 if (prevgre == NULL)
5422                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
5423                                 else
5424                                         prevgre->hashlink = gre->hashlink;
5425
5426                                 FREE(gre, hashtable_global_ref_entry);
5427                         }
5428
5429                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5430
5431                         return;
5432                 }
5433
5434                 prevgre = gre;                    /* save current pointer for removal */
5435                 gre     = gre->hashlink;            /* next element in external chain */
5436         }
5437
5438         log_println("JNI-DeleteGlobalRef: global reference not found");
5439
5440         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
5441 }
5442
5443
5444 /* ExceptionCheck **************************************************************
5445
5446    Returns JNI_TRUE when there is a pending exception; otherwise,
5447    returns JNI_FALSE.
5448
5449 *******************************************************************************/
5450
5451 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
5452 {
5453         java_objectheader *o;
5454
5455         STATISTICS(jniinvokation());
5456
5457         o = exceptions_get_exception();
5458
5459         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
5460 }
5461
5462
5463 /* New JNI 1.4 functions ******************************************************/
5464
5465 /* NewDirectByteBuffer *********************************************************
5466
5467    Allocates and returns a direct java.nio.ByteBuffer referring to the
5468    block of memory starting at the memory address address and
5469    extending capacity bytes.
5470
5471 *******************************************************************************/
5472
5473 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
5474 {
5475 #if defined(ENABLE_JAVASE)
5476         java_objectheader       *nbuf;
5477 # if SIZEOF_VOID_P == 8
5478         gnu_classpath_Pointer64 *paddress;
5479 # else
5480         gnu_classpath_Pointer32 *paddress;
5481 # endif
5482
5483         STATISTICS(jniinvokation());
5484
5485         /* alocate a gnu.classpath.Pointer{32,64} object */
5486
5487 # if SIZEOF_VOID_P == 8
5488         if (!(paddress = (gnu_classpath_Pointer64 *)
5489                   builtin_new(class_gnu_classpath_Pointer64)))
5490 # else
5491         if (!(paddress = (gnu_classpath_Pointer32 *)
5492                   builtin_new(class_gnu_classpath_Pointer32)))
5493 # endif
5494                 return NULL;
5495
5496         /* fill gnu.classpath.Pointer{32,64} with address */
5497
5498         paddress->data = (ptrint) address;
5499
5500         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
5501
5502         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
5503                                                          (jmethodID) dbbirw_init, NULL, paddress,
5504                                                          (jint) capacity, (jint) capacity, (jint) 0);
5505
5506         /* add local reference and return the value */
5507
5508         return _Jv_JNI_NewLocalRef(env, nbuf);
5509 #else
5510         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
5511
5512         /* keep compiler happy */
5513
5514         return NULL;
5515 #endif
5516 }
5517
5518
5519 /* GetDirectBufferAddress ******************************************************
5520
5521    Fetches and returns the starting address of the memory region
5522    referenced by the given direct java.nio.Buffer.
5523
5524 *******************************************************************************/
5525
5526 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
5527 {
5528 #if defined(ENABLE_JAVASE)
5529         java_nio_DirectByteBufferImpl *nbuf;
5530 # if SIZEOF_VOID_P == 8
5531         gnu_classpath_Pointer64       *address;
5532 # else
5533         gnu_classpath_Pointer32       *address;
5534 # endif
5535
5536         STATISTICS(jniinvokation());
5537
5538         if (!builtin_instanceof(buf, class_java_nio_Buffer))
5539                 return NULL;
5540
5541         nbuf = (java_nio_DirectByteBufferImpl *) buf;
5542
5543 # if SIZEOF_VOID_P == 8
5544         address = (gnu_classpath_Pointer64 *) nbuf->address;
5545 # else
5546         address = (gnu_classpath_Pointer32 *) nbuf->address;
5547 # endif
5548
5549         if (address == NULL)
5550                 return NULL;
5551
5552         return (void *) address->data;
5553 #else
5554         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
5555
5556         /* keep compiler happy */
5557
5558         return NULL;
5559 #endif
5560 }
5561
5562
5563 /* GetDirectBufferCapacity *****************************************************
5564
5565    Fetches and returns the capacity in bytes of the memory region
5566    referenced by the given direct java.nio.Buffer.
5567
5568 *******************************************************************************/
5569
5570 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
5571 {
5572 #if defined(ENABLE_JAVASE)
5573         java_nio_Buffer *nbuf;
5574
5575         STATISTICS(jniinvokation());
5576
5577         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
5578                 return -1;
5579
5580         nbuf = (java_nio_Buffer *) buf;
5581
5582         return (jlong) nbuf->cap;
5583 #else
5584         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
5585
5586         /* keep compiler happy */
5587
5588         return 0;
5589 #endif
5590 }
5591
5592
5593 /* DestroyJavaVM ***************************************************************
5594
5595    Unloads a Java VM and reclaims its resources. Only the main thread
5596    can unload the VM. The system waits until the main thread is only
5597    remaining user thread before it destroys the VM.
5598
5599 *******************************************************************************/
5600
5601 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
5602 {
5603         s4 status;
5604
5605         STATISTICS(jniinvokation());
5606
5607     status = vm_destroy(vm);
5608
5609         return status;
5610 }
5611
5612
5613 /* AttachCurrentThread *********************************************************
5614
5615    Attaches the current thread to a Java VM. Returns a JNI interface
5616    pointer in the JNIEnv argument.
5617
5618    Trying to attach a thread that is already attached is a no-op.
5619
5620    A native thread cannot be attached simultaneously to two Java VMs.
5621
5622    When a thread is attached to the VM, the context class loader is
5623    the bootstrap loader.
5624
5625 *******************************************************************************/
5626
5627 static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
5628 {
5629         JavaVMAttachArgs *vm_aargs;
5630
5631 #if defined(ENABLE_THREADS)
5632         if (threads_get_current_threadobject() == NULL) {
5633                 vm_aargs = (JavaVMAttachArgs *) thr_args;
5634
5635                 if (vm_aargs != NULL) {
5636                         if ((vm_aargs->version != JNI_VERSION_1_2) &&
5637                                 (vm_aargs->version != JNI_VERSION_1_4))
5638                                 return JNI_EVERSION;
5639                 }
5640
5641                 if (!threads_attach_current_thread(vm_aargs, false))
5642                         return JNI_ERR;
5643
5644                 if (!jni_init_localref_table())
5645                         return JNI_ERR;
5646         }
5647 #endif
5648
5649         *p_env = _Jv_env;
5650
5651         return JNI_OK;
5652 }
5653
5654
5655 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
5656 {
5657         STATISTICS(jniinvokation());
5658
5659         return jni_attach_current_thread(p_env, thr_args, false);
5660 }
5661
5662
5663 /* DetachCurrentThread *********************************************************
5664
5665    Detaches the current thread from a Java VM. All Java monitors held
5666    by this thread are released. All Java threads waiting for this
5667    thread to die are notified.
5668
5669    In JDK 1.1, the main thread cannot be detached from the VM. It must
5670    call DestroyJavaVM to unload the entire VM.
5671
5672    In the JDK, the main thread can be detached from the VM.
5673
5674    The main thread, which is the thread that created the Java VM,
5675    cannot be detached from the VM. Instead, the main thread must call
5676    JNI_DestroyJavaVM() to unload the entire VM.
5677
5678 *******************************************************************************/
5679
5680 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
5681 {
5682 #if defined(ENABLE_THREADS)
5683         threadobject *thread;
5684
5685         STATISTICS(jniinvokation());
5686
5687         thread = threads_get_current_threadobject();
5688
5689         if (thread == NULL)
5690                 return JNI_ERR;
5691
5692         if (!threads_detach_thread(thread))
5693                 return JNI_ERR;
5694 #endif
5695
5696         return JNI_OK;
5697 }
5698
5699
5700 /* GetEnv **********************************************************************
5701
5702    If the current thread is not attached to the VM, sets *env to NULL,
5703    and returns JNI_EDETACHED. If the specified version is not
5704    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
5705    sets *env to the appropriate interface, and returns JNI_OK.
5706
5707 *******************************************************************************/
5708
5709 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
5710 {
5711         STATISTICS(jniinvokation());
5712
5713 #if defined(ENABLE_THREADS)
5714         if (threads_get_current_threadobject() == NULL) {
5715                 *env = NULL;
5716
5717                 return JNI_EDETACHED;
5718         }
5719 #endif
5720
5721         /* check the JNI version */
5722
5723         switch (version) {
5724         case JNI_VERSION_1_1:
5725         case JNI_VERSION_1_2:
5726         case JNI_VERSION_1_4:
5727                 *env = _Jv_env;
5728                 return JNI_OK;
5729
5730         default:
5731                 ;
5732         }
5733
5734 #if defined(ENABLE_JVMTI)
5735         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
5736                 == JVMTI_VERSION_INTERFACE_JVMTI) {
5737
5738                 *env = (void *) jvmti_new_environment();
5739
5740                 if (env != NULL)
5741                         return JNI_OK;
5742         }
5743 #endif
5744         
5745         *env = NULL;
5746
5747         return JNI_EVERSION;
5748 }
5749
5750
5751 /* AttachCurrentThreadAsDaemon *************************************************
5752
5753    Same semantics as AttachCurrentThread, but the newly-created
5754    java.lang.Thread instance is a daemon.
5755
5756    If the thread has already been attached via either
5757    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
5758    simply sets the value pointed to by penv to the JNIEnv of the
5759    current thread. In this case neither AttachCurrentThread nor this
5760    routine have any effect on the daemon status of the thread.
5761
5762 *******************************************************************************/
5763
5764 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
5765 {
5766         STATISTICS(jniinvokation());
5767
5768         return jni_attach_current_thread(penv, args, true);
5769 }
5770
5771
5772 /* JNI invocation table *******************************************************/
5773
5774 const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
5775         NULL,
5776         NULL,
5777         NULL,
5778
5779         _Jv_JNI_DestroyJavaVM,
5780         _Jv_JNI_AttachCurrentThread,
5781         _Jv_JNI_DetachCurrentThread,
5782         _Jv_JNI_GetEnv,
5783         _Jv_JNI_AttachCurrentThreadAsDaemon
5784 };
5785
5786
5787 /* JNI function table *********************************************************/
5788
5789 struct JNINativeInterface _Jv_JNINativeInterface = {
5790         NULL,
5791         NULL,
5792         NULL,
5793         NULL,    
5794         _Jv_JNI_GetVersion,
5795
5796         _Jv_JNI_DefineClass,
5797         _Jv_JNI_FindClass,
5798         _Jv_JNI_FromReflectedMethod,
5799         _Jv_JNI_FromReflectedField,
5800         _Jv_JNI_ToReflectedMethod,
5801         _Jv_JNI_GetSuperclass,
5802         _Jv_JNI_IsAssignableFrom,
5803         _Jv_JNI_ToReflectedField,
5804
5805         _Jv_JNI_Throw,
5806         _Jv_JNI_ThrowNew,
5807         _Jv_JNI_ExceptionOccurred,
5808         _Jv_JNI_ExceptionDescribe,
5809         _Jv_JNI_ExceptionClear,
5810         _Jv_JNI_FatalError,
5811         _Jv_JNI_PushLocalFrame,
5812         _Jv_JNI_PopLocalFrame,
5813
5814         _Jv_JNI_NewGlobalRef,
5815         _Jv_JNI_DeleteGlobalRef,
5816         _Jv_JNI_DeleteLocalRef,
5817         _Jv_JNI_IsSameObject,
5818         _Jv_JNI_NewLocalRef,
5819         _Jv_JNI_EnsureLocalCapacity,
5820
5821         _Jv_JNI_AllocObject,
5822         _Jv_JNI_NewObject,
5823         _Jv_JNI_NewObjectV,
5824         _Jv_JNI_NewObjectA,
5825
5826         _Jv_JNI_GetObjectClass,
5827         _Jv_JNI_IsInstanceOf,
5828
5829         _Jv_JNI_GetMethodID,
5830
5831         _Jv_JNI_CallObjectMethod,
5832         _Jv_JNI_CallObjectMethodV,
5833         _Jv_JNI_CallObjectMethodA,
5834         _Jv_JNI_CallBooleanMethod,
5835         _Jv_JNI_CallBooleanMethodV,
5836         _Jv_JNI_CallBooleanMethodA,
5837         _Jv_JNI_CallByteMethod,
5838         _Jv_JNI_CallByteMethodV,
5839         _Jv_JNI_CallByteMethodA,
5840         _Jv_JNI_CallCharMethod,
5841         _Jv_JNI_CallCharMethodV,
5842         _Jv_JNI_CallCharMethodA,
5843         _Jv_JNI_CallShortMethod,
5844         _Jv_JNI_CallShortMethodV,
5845         _Jv_JNI_CallShortMethodA,
5846         _Jv_JNI_CallIntMethod,
5847         _Jv_JNI_CallIntMethodV,
5848         _Jv_JNI_CallIntMethodA,
5849         _Jv_JNI_CallLongMethod,
5850         _Jv_JNI_CallLongMethodV,
5851         _Jv_JNI_CallLongMethodA,
5852         _Jv_JNI_CallFloatMethod,
5853         _Jv_JNI_CallFloatMethodV,
5854         _Jv_JNI_CallFloatMethodA,
5855         _Jv_JNI_CallDoubleMethod,
5856         _Jv_JNI_CallDoubleMethodV,
5857         _Jv_JNI_CallDoubleMethodA,
5858         _Jv_JNI_CallVoidMethod,
5859         _Jv_JNI_CallVoidMethodV,
5860         _Jv_JNI_CallVoidMethodA,
5861
5862         _Jv_JNI_CallNonvirtualObjectMethod,
5863         _Jv_JNI_CallNonvirtualObjectMethodV,
5864         _Jv_JNI_CallNonvirtualObjectMethodA,
5865         _Jv_JNI_CallNonvirtualBooleanMethod,
5866         _Jv_JNI_CallNonvirtualBooleanMethodV,
5867         _Jv_JNI_CallNonvirtualBooleanMethodA,
5868         _Jv_JNI_CallNonvirtualByteMethod,
5869         _Jv_JNI_CallNonvirtualByteMethodV,
5870         _Jv_JNI_CallNonvirtualByteMethodA,
5871         _Jv_JNI_CallNonvirtualCharMethod,
5872         _Jv_JNI_CallNonvirtualCharMethodV,
5873         _Jv_JNI_CallNonvirtualCharMethodA,
5874         _Jv_JNI_CallNonvirtualShortMethod,
5875         _Jv_JNI_CallNonvirtualShortMethodV,
5876         _Jv_JNI_CallNonvirtualShortMethodA,
5877         _Jv_JNI_CallNonvirtualIntMethod,
5878         _Jv_JNI_CallNonvirtualIntMethodV,
5879         _Jv_JNI_CallNonvirtualIntMethodA,
5880         _Jv_JNI_CallNonvirtualLongMethod,
5881         _Jv_JNI_CallNonvirtualLongMethodV,
5882         _Jv_JNI_CallNonvirtualLongMethodA,
5883         _Jv_JNI_CallNonvirtualFloatMethod,
5884         _Jv_JNI_CallNonvirtualFloatMethodV,
5885         _Jv_JNI_CallNonvirtualFloatMethodA,
5886         _Jv_JNI_CallNonvirtualDoubleMethod,
5887         _Jv_JNI_CallNonvirtualDoubleMethodV,
5888         _Jv_JNI_CallNonvirtualDoubleMethodA,
5889         _Jv_JNI_CallNonvirtualVoidMethod,
5890         _Jv_JNI_CallNonvirtualVoidMethodV,
5891         _Jv_JNI_CallNonvirtualVoidMethodA,
5892
5893         _Jv_JNI_GetFieldID,
5894
5895         _Jv_JNI_GetObjectField,
5896         _Jv_JNI_GetBooleanField,
5897         _Jv_JNI_GetByteField,
5898         _Jv_JNI_GetCharField,
5899         _Jv_JNI_GetShortField,
5900         _Jv_JNI_GetIntField,
5901         _Jv_JNI_GetLongField,
5902         _Jv_JNI_GetFloatField,
5903         _Jv_JNI_GetDoubleField,
5904         _Jv_JNI_SetObjectField,
5905         _Jv_JNI_SetBooleanField,
5906         _Jv_JNI_SetByteField,
5907         _Jv_JNI_SetCharField,
5908         _Jv_JNI_SetShortField,
5909         _Jv_JNI_SetIntField,
5910         _Jv_JNI_SetLongField,
5911         _Jv_JNI_SetFloatField,
5912         _Jv_JNI_SetDoubleField,
5913
5914         _Jv_JNI_GetStaticMethodID,
5915
5916         _Jv_JNI_CallStaticObjectMethod,
5917         _Jv_JNI_CallStaticObjectMethodV,
5918         _Jv_JNI_CallStaticObjectMethodA,
5919         _Jv_JNI_CallStaticBooleanMethod,
5920         _Jv_JNI_CallStaticBooleanMethodV,
5921         _Jv_JNI_CallStaticBooleanMethodA,
5922         _Jv_JNI_CallStaticByteMethod,
5923         _Jv_JNI_CallStaticByteMethodV,
5924         _Jv_JNI_CallStaticByteMethodA,
5925         _Jv_JNI_CallStaticCharMethod,
5926         _Jv_JNI_CallStaticCharMethodV,
5927         _Jv_JNI_CallStaticCharMethodA,
5928         _Jv_JNI_CallStaticShortMethod,
5929         _Jv_JNI_CallStaticShortMethodV,
5930         _Jv_JNI_CallStaticShortMethodA,
5931         _Jv_JNI_CallStaticIntMethod,
5932         _Jv_JNI_CallStaticIntMethodV,
5933         _Jv_JNI_CallStaticIntMethodA,
5934         _Jv_JNI_CallStaticLongMethod,
5935         _Jv_JNI_CallStaticLongMethodV,
5936         _Jv_JNI_CallStaticLongMethodA,
5937         _Jv_JNI_CallStaticFloatMethod,
5938         _Jv_JNI_CallStaticFloatMethodV,
5939         _Jv_JNI_CallStaticFloatMethodA,
5940         _Jv_JNI_CallStaticDoubleMethod,
5941         _Jv_JNI_CallStaticDoubleMethodV,
5942         _Jv_JNI_CallStaticDoubleMethodA,
5943         _Jv_JNI_CallStaticVoidMethod,
5944         _Jv_JNI_CallStaticVoidMethodV,
5945         _Jv_JNI_CallStaticVoidMethodA,
5946
5947         _Jv_JNI_GetStaticFieldID,
5948
5949         _Jv_JNI_GetStaticObjectField,
5950         _Jv_JNI_GetStaticBooleanField,
5951         _Jv_JNI_GetStaticByteField,
5952         _Jv_JNI_GetStaticCharField,
5953         _Jv_JNI_GetStaticShortField,
5954         _Jv_JNI_GetStaticIntField,
5955         _Jv_JNI_GetStaticLongField,
5956         _Jv_JNI_GetStaticFloatField,
5957         _Jv_JNI_GetStaticDoubleField,
5958         _Jv_JNI_SetStaticObjectField,
5959         _Jv_JNI_SetStaticBooleanField,
5960         _Jv_JNI_SetStaticByteField,
5961         _Jv_JNI_SetStaticCharField,
5962         _Jv_JNI_SetStaticShortField,
5963         _Jv_JNI_SetStaticIntField,
5964         _Jv_JNI_SetStaticLongField,
5965         _Jv_JNI_SetStaticFloatField,
5966         _Jv_JNI_SetStaticDoubleField,
5967
5968         _Jv_JNI_NewString,
5969         _Jv_JNI_GetStringLength,
5970         _Jv_JNI_GetStringChars,
5971         _Jv_JNI_ReleaseStringChars,
5972
5973         _Jv_JNI_NewStringUTF,
5974         _Jv_JNI_GetStringUTFLength,
5975         _Jv_JNI_GetStringUTFChars,
5976         _Jv_JNI_ReleaseStringUTFChars,
5977
5978         _Jv_JNI_GetArrayLength,
5979
5980         _Jv_JNI_NewObjectArray,
5981         _Jv_JNI_GetObjectArrayElement,
5982         _Jv_JNI_SetObjectArrayElement,
5983
5984         _Jv_JNI_NewBooleanArray,
5985         _Jv_JNI_NewByteArray,
5986         _Jv_JNI_NewCharArray,
5987         _Jv_JNI_NewShortArray,
5988         _Jv_JNI_NewIntArray,
5989         _Jv_JNI_NewLongArray,
5990         _Jv_JNI_NewFloatArray,
5991         _Jv_JNI_NewDoubleArray,
5992
5993         _Jv_JNI_GetBooleanArrayElements,
5994         _Jv_JNI_GetByteArrayElements,
5995         _Jv_JNI_GetCharArrayElements,
5996         _Jv_JNI_GetShortArrayElements,
5997         _Jv_JNI_GetIntArrayElements,
5998         _Jv_JNI_GetLongArrayElements,
5999         _Jv_JNI_GetFloatArrayElements,
6000         _Jv_JNI_GetDoubleArrayElements,
6001
6002         _Jv_JNI_ReleaseBooleanArrayElements,
6003         _Jv_JNI_ReleaseByteArrayElements,
6004         _Jv_JNI_ReleaseCharArrayElements,
6005         _Jv_JNI_ReleaseShortArrayElements,
6006         _Jv_JNI_ReleaseIntArrayElements,
6007         _Jv_JNI_ReleaseLongArrayElements,
6008         _Jv_JNI_ReleaseFloatArrayElements,
6009         _Jv_JNI_ReleaseDoubleArrayElements,
6010
6011         _Jv_JNI_GetBooleanArrayRegion,
6012         _Jv_JNI_GetByteArrayRegion,
6013         _Jv_JNI_GetCharArrayRegion,
6014         _Jv_JNI_GetShortArrayRegion,
6015         _Jv_JNI_GetIntArrayRegion,
6016         _Jv_JNI_GetLongArrayRegion,
6017         _Jv_JNI_GetFloatArrayRegion,
6018         _Jv_JNI_GetDoubleArrayRegion,
6019         _Jv_JNI_SetBooleanArrayRegion,
6020         _Jv_JNI_SetByteArrayRegion,
6021         _Jv_JNI_SetCharArrayRegion,
6022         _Jv_JNI_SetShortArrayRegion,
6023         _Jv_JNI_SetIntArrayRegion,
6024         _Jv_JNI_SetLongArrayRegion,
6025         _Jv_JNI_SetFloatArrayRegion,
6026         _Jv_JNI_SetDoubleArrayRegion,
6027
6028         _Jv_JNI_RegisterNatives,
6029         _Jv_JNI_UnregisterNatives,
6030
6031         _Jv_JNI_MonitorEnter,
6032         _Jv_JNI_MonitorExit,
6033
6034         _Jv_JNI_GetJavaVM,
6035
6036         /* new JNI 1.2 functions */
6037
6038         _Jv_JNI_GetStringRegion,
6039         _Jv_JNI_GetStringUTFRegion,
6040
6041         _Jv_JNI_GetPrimitiveArrayCritical,
6042         _Jv_JNI_ReleasePrimitiveArrayCritical,
6043
6044         _Jv_JNI_GetStringCritical,
6045         _Jv_JNI_ReleaseStringCritical,
6046
6047         _Jv_JNI_NewWeakGlobalRef,
6048         _Jv_JNI_DeleteWeakGlobalRef,
6049
6050         _Jv_JNI_ExceptionCheck,
6051
6052         /* new JNI 1.4 functions */
6053
6054         _Jv_JNI_NewDirectByteBuffer,
6055         _Jv_JNI_GetDirectBufferAddress,
6056         _Jv_JNI_GetDirectBufferCapacity
6057 };
6058
6059
6060 /* Invocation API Functions ***************************************************/
6061
6062 /* JNI_GetDefaultJavaVMInitArgs ************************************************
6063
6064    Returns a default configuration for the Java VM.
6065
6066 *******************************************************************************/
6067
6068 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
6069 {
6070         JavaVMInitArgs *_vm_args;
6071
6072         _vm_args = (JavaVMInitArgs *) vm_args;
6073
6074         /* GNU classpath currently supports JNI 1.2 */
6075
6076         switch (_vm_args->version) {
6077     case JNI_VERSION_1_1:
6078                 _vm_args->version = JNI_VERSION_1_1;
6079                 break;
6080
6081     case JNI_VERSION_1_2:
6082     case JNI_VERSION_1_4:
6083                 _vm_args->ignoreUnrecognized = JNI_FALSE;
6084                 _vm_args->options = NULL;
6085                 _vm_args->nOptions = 0;
6086                 break;
6087
6088     default:
6089                 return -1;
6090         }
6091   
6092         return 0;
6093 }
6094
6095
6096 /* JNI_GetCreatedJavaVMs *******************************************************
6097
6098    Returns all Java VMs that have been created. Pointers to VMs are written in
6099    the buffer vmBuf in the order they are created. At most bufLen number of
6100    entries will be written. The total number of created VMs is returned in
6101    *nVMs.
6102
6103 *******************************************************************************/
6104
6105 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
6106 {
6107         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
6108
6109         return 0;
6110 }
6111
6112
6113 /* JNI_CreateJavaVM ************************************************************
6114
6115    Loads and initializes a Java VM. The current thread becomes the main thread.
6116    Sets the env argument to the JNI interface pointer of the main thread.
6117
6118 *******************************************************************************/
6119
6120 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
6121 {
6122         /* actually create the JVM */
6123
6124         if (!vm_createjvm(p_vm, p_env, vm_args))
6125                 return JNI_ERR;
6126
6127         return JNI_OK;
6128 }
6129
6130
6131 /*
6132  * These are local overrides for various environment variables in Emacs.
6133  * Please do not remove this and leave it at the end of the file, where
6134  * Emacs will automagically detect them.
6135  * ---------------------------------------------------------------------
6136  * Local variables:
6137  * mode: c
6138  * indent-tabs-mode: t
6139  * c-basic-offset: 4
6140  * tab-width: 4
6141  * End:
6142  * vim:noexpandtab:sw=4:ts=4:
6143  */