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