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