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