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