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