42c90facfd35f88fbade495e72406c50ae929c27
[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 4082 2006-01-03 23:08:58Z 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         *exceptionptr = new_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                 *exceptionptr = new_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                 *exceptionptr =
3315                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3316
3317                 return NULL;
3318         }
3319
3320         o = array->data[index];
3321     
3322     return NewLocalRef(env, o);
3323 }
3324
3325
3326 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3327 {
3328         java_objectarray  *oa;
3329         java_objectheader *o;
3330
3331         STATISTICS(jniinvokation());
3332
3333         oa = (java_objectarray *) array;
3334         o  = (java_objectheader *) val;
3335
3336     if (index >= array->header.size) {
3337                 *exceptionptr =
3338                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3339
3340                 return;
3341         }
3342
3343         /* check if the class of value is a subclass of the element class
3344            of the array */
3345
3346         if (!builtin_canstore(oa, o)) {
3347                 *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3348
3349                 return;
3350         }
3351
3352         array->data[index] = val;
3353 }
3354
3355
3356 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3357 {
3358         java_booleanarray *ba;
3359
3360         STATISTICS(jniinvokation());
3361
3362         if (len < 0) {
3363                 *exceptionptr = new_negativearraysizeexception();
3364                 return NULL;
3365         }
3366
3367         ba = builtin_newarray_boolean(len);
3368
3369         return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3370 }
3371
3372
3373 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3374 {
3375         java_bytearray *ba;
3376
3377         STATISTICS(jniinvokation());
3378
3379         if (len < 0) {
3380                 *exceptionptr = new_negativearraysizeexception();
3381                 return NULL;
3382         }
3383
3384         ba = builtin_newarray_byte(len);
3385
3386         return (jbyteArray) NewLocalRef(env, (jobject) ba);
3387 }
3388
3389
3390 jcharArray NewCharArray(JNIEnv *env, jsize len)
3391 {
3392         java_chararray *ca;
3393
3394         STATISTICS(jniinvokation());
3395
3396         if (len < 0) {
3397                 *exceptionptr = new_negativearraysizeexception();
3398                 return NULL;
3399         }
3400
3401         ca = builtin_newarray_char(len);
3402
3403         return (jcharArray) NewLocalRef(env, (jobject) ca);
3404 }
3405
3406
3407 jshortArray NewShortArray(JNIEnv *env, jsize len)
3408 {
3409         java_shortarray *sa;
3410
3411         STATISTICS(jniinvokation());
3412
3413         if (len < 0) {
3414                 *exceptionptr = new_negativearraysizeexception();
3415                 return NULL;
3416         }
3417
3418         sa = builtin_newarray_short(len);
3419
3420         return (jshortArray) NewLocalRef(env, (jobject) sa);
3421 }
3422
3423
3424 jintArray NewIntArray(JNIEnv *env, jsize len)
3425 {
3426         java_intarray *ia;
3427
3428         STATISTICS(jniinvokation());
3429
3430         if (len < 0) {
3431                 *exceptionptr = new_negativearraysizeexception();
3432                 return NULL;
3433         }
3434
3435         ia = builtin_newarray_int(len);
3436
3437         return (jintArray) NewLocalRef(env, (jobject) ia);
3438 }
3439
3440
3441 jlongArray NewLongArray(JNIEnv *env, jsize len)
3442 {
3443         java_longarray *la;
3444
3445         STATISTICS(jniinvokation());
3446
3447         if (len < 0) {
3448                 *exceptionptr = new_negativearraysizeexception();
3449                 return NULL;
3450         }
3451
3452         la = builtin_newarray_long(len);
3453
3454         return (jlongArray) NewLocalRef(env, (jobject) la);
3455 }
3456
3457
3458 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3459 {
3460         java_floatarray *fa;
3461
3462         STATISTICS(jniinvokation());
3463
3464         if (len < 0) {
3465                 *exceptionptr = new_negativearraysizeexception();
3466                 return NULL;
3467         }
3468
3469         fa = builtin_newarray_float(len);
3470
3471         return (jfloatArray) NewLocalRef(env, (jobject) fa);
3472 }
3473
3474
3475 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3476 {
3477         java_doublearray *da;
3478
3479         STATISTICS(jniinvokation());
3480
3481         if (len < 0) {
3482                 *exceptionptr = new_negativearraysizeexception();
3483                 return NULL;
3484         }
3485
3486         da = builtin_newarray_double(len);
3487
3488         return (jdoubleArray) NewLocalRef(env, (jobject) da);
3489 }
3490
3491
3492 /* Get<PrimitiveType>ArrayElements *********************************************
3493
3494    A family of functions that returns the body of the primitive array.
3495
3496 *******************************************************************************/
3497
3498 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3499                                                                   jboolean *isCopy)
3500 {
3501         STATISTICS(jniinvokation());
3502
3503     if (isCopy)
3504                 *isCopy = JNI_FALSE;
3505
3506     return array->data;
3507 }
3508
3509
3510 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3511 {
3512         STATISTICS(jniinvokation());
3513
3514     if (isCopy)
3515                 *isCopy = JNI_FALSE;
3516
3517     return array->data;
3518 }
3519
3520
3521 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3522 {
3523         STATISTICS(jniinvokation());
3524
3525     if (isCopy)
3526                 *isCopy = JNI_FALSE;
3527
3528     return array->data;
3529 }
3530
3531
3532 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3533 {
3534         STATISTICS(jniinvokation());
3535
3536     if (isCopy)
3537                 *isCopy = JNI_FALSE;
3538
3539     return array->data;
3540 }
3541
3542
3543 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3544 {
3545         STATISTICS(jniinvokation());
3546
3547     if (isCopy)
3548                 *isCopy = JNI_FALSE;
3549
3550     return array->data;
3551 }
3552
3553
3554 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3555 {
3556         STATISTICS(jniinvokation());
3557
3558     if (isCopy)
3559                 *isCopy = JNI_FALSE;
3560
3561     return array->data;
3562 }
3563
3564
3565 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3566 {
3567         STATISTICS(jniinvokation());
3568
3569     if (isCopy)
3570                 *isCopy = JNI_FALSE;
3571
3572     return array->data;
3573 }
3574
3575
3576 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3577                                                                 jboolean *isCopy)
3578 {
3579         STATISTICS(jniinvokation());
3580
3581     if (isCopy)
3582                 *isCopy = JNI_FALSE;
3583
3584     return array->data;
3585 }
3586
3587
3588 /* Release<PrimitiveType>ArrayElements *****************************************
3589
3590    A family of functions that informs the VM that the native code no
3591    longer needs access to elems. The elems argument is a pointer
3592    derived from array using the corresponding
3593    Get<PrimitiveType>ArrayElements() function. If necessary, this
3594    function copies back all changes made to elems to the original
3595    array.
3596
3597 *******************************************************************************/
3598
3599 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3600                                                                  jboolean *elems, jint mode)
3601 {
3602         STATISTICS(jniinvokation());
3603
3604         if (elems != array->data) {
3605                 switch (mode) {
3606                 case JNI_COMMIT:
3607                         MCOPY(array->data, elems, jboolean, array->header.size);
3608                         break;
3609                 case 0:
3610                         MCOPY(array->data, elems, jboolean, array->header.size);
3611                         /* XXX TWISTI how should it be freed? */
3612                         break;
3613                 case JNI_ABORT:
3614                         /* XXX TWISTI how should it be freed? */
3615                         break;
3616                 }
3617         }
3618 }
3619
3620
3621 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3622                                                           jint mode)
3623 {
3624         STATISTICS(jniinvokation());
3625
3626         if (elems != array->data) {
3627                 switch (mode) {
3628                 case JNI_COMMIT:
3629                         MCOPY(array->data, elems, jboolean, array->header.size);
3630                         break;
3631                 case 0:
3632                         MCOPY(array->data, elems, jboolean, array->header.size);
3633                         /* XXX TWISTI how should it be freed? */
3634                         break;
3635                 case JNI_ABORT:
3636                         /* XXX TWISTI how should it be freed? */
3637                         break;
3638                 }
3639         }
3640 }
3641
3642
3643 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3644                                                           jint mode)
3645 {
3646         STATISTICS(jniinvokation());
3647
3648         if (elems != array->data) {
3649                 switch (mode) {
3650                 case JNI_COMMIT:
3651                         MCOPY(array->data, elems, jboolean, array->header.size);
3652                         break;
3653                 case 0:
3654                         MCOPY(array->data, elems, jboolean, array->header.size);
3655                         /* XXX TWISTI how should it be freed? */
3656                         break;
3657                 case JNI_ABORT:
3658                         /* XXX TWISTI how should it be freed? */
3659                         break;
3660                 }
3661         }
3662 }
3663
3664
3665 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3666                                                            jint mode)
3667 {
3668         STATISTICS(jniinvokation());
3669
3670         if (elems != array->data) {
3671                 switch (mode) {
3672                 case JNI_COMMIT:
3673                         MCOPY(array->data, elems, jboolean, array->header.size);
3674                         break;
3675                 case 0:
3676                         MCOPY(array->data, elems, jboolean, array->header.size);
3677                         /* XXX TWISTI how should it be freed? */
3678                         break;
3679                 case JNI_ABORT:
3680                         /* XXX TWISTI how should it be freed? */
3681                         break;
3682                 }
3683         }
3684 }
3685
3686
3687 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3688                                                          jint mode)
3689 {
3690         STATISTICS(jniinvokation());
3691
3692         if (elems != array->data) {
3693                 switch (mode) {
3694                 case JNI_COMMIT:
3695                         MCOPY(array->data, elems, jboolean, array->header.size);
3696                         break;
3697                 case 0:
3698                         MCOPY(array->data, elems, jboolean, array->header.size);
3699                         /* XXX TWISTI how should it be freed? */
3700                         break;
3701                 case JNI_ABORT:
3702                         /* XXX TWISTI how should it be freed? */
3703                         break;
3704                 }
3705         }
3706 }
3707
3708
3709 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3710                                                           jint mode)
3711 {
3712         STATISTICS(jniinvokation());
3713
3714         if (elems != array->data) {
3715                 switch (mode) {
3716                 case JNI_COMMIT:
3717                         MCOPY(array->data, elems, jboolean, array->header.size);
3718                         break;
3719                 case 0:
3720                         MCOPY(array->data, elems, jboolean, array->header.size);
3721                         /* XXX TWISTI how should it be freed? */
3722                         break;
3723                 case JNI_ABORT:
3724                         /* XXX TWISTI how should it be freed? */
3725                         break;
3726                 }
3727         }
3728 }
3729
3730
3731 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3732                                                            jint mode)
3733 {
3734         STATISTICS(jniinvokation());
3735
3736         if (elems != array->data) {
3737                 switch (mode) {
3738                 case JNI_COMMIT:
3739                         MCOPY(array->data, elems, jboolean, array->header.size);
3740                         break;
3741                 case 0:
3742                         MCOPY(array->data, elems, jboolean, array->header.size);
3743                         /* XXX TWISTI how should it be freed? */
3744                         break;
3745                 case JNI_ABORT:
3746                         /* XXX TWISTI how should it be freed? */
3747                         break;
3748                 }
3749         }
3750 }
3751
3752
3753 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3754                                                                 jdouble *elems, jint mode)
3755 {
3756         STATISTICS(jniinvokation());
3757
3758         if (elems != array->data) {
3759                 switch (mode) {
3760                 case JNI_COMMIT:
3761                         MCOPY(array->data, elems, jboolean, array->header.size);
3762                         break;
3763                 case 0:
3764                         MCOPY(array->data, elems, jboolean, array->header.size);
3765                         /* XXX TWISTI how should it be freed? */
3766                         break;
3767                 case JNI_ABORT:
3768                         /* XXX TWISTI how should it be freed? */
3769                         break;
3770                 }
3771         }
3772 }
3773
3774
3775 /*  Get<PrimitiveType>ArrayRegion **********************************************
3776
3777         A family of functions that copies a region of a primitive array
3778         into a buffer.
3779
3780 *******************************************************************************/
3781
3782 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3783                                                    jsize len, jboolean *buf)
3784 {
3785         STATISTICS(jniinvokation());
3786
3787     if (start < 0 || len < 0 || start + len > array->header.size)
3788                 *exceptionptr =
3789                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3790
3791     else
3792                 MCOPY(buf, &array->data[start], jboolean, len);
3793 }
3794
3795
3796 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3797                                                 jbyte *buf)
3798 {
3799         STATISTICS(jniinvokation());
3800
3801     if (start < 0 || len < 0 || start + len > array->header.size) 
3802                 *exceptionptr =
3803                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3804
3805     else
3806                 MCOPY(buf, &array->data[start], jbyte, len);
3807 }
3808
3809
3810 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3811                                                 jchar *buf)
3812 {
3813         STATISTICS(jniinvokation());
3814
3815     if (start < 0 || len < 0 || start + len > array->header.size)
3816                 *exceptionptr =
3817                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3818
3819     else
3820                 MCOPY(buf, &array->data[start], jchar, len);
3821 }
3822
3823
3824 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3825                                                  jsize len, jshort *buf)
3826 {
3827         STATISTICS(jniinvokation());
3828
3829     if (start < 0 || len < 0 || start + len > array->header.size)
3830                 *exceptionptr =
3831                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3832
3833     else        
3834                 MCOPY(buf, &array->data[start], jshort, len);
3835 }
3836
3837
3838 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3839                                            jint *buf)
3840 {
3841         STATISTICS(jniinvokation());
3842
3843     if (start < 0 || len < 0 || start + len > array->header.size)
3844                 *exceptionptr =
3845                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3846
3847     else
3848                 MCOPY(buf, &array->data[start], jint, len);
3849 }
3850
3851
3852 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3853                                                 jlong *buf)
3854 {
3855         STATISTICS(jniinvokation());
3856
3857     if (start < 0 || len < 0 || start + len > array->header.size)
3858                 *exceptionptr =
3859                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3860
3861     else
3862                 MCOPY(buf, &array->data[start], jlong, len);
3863 }
3864
3865
3866 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3867                                                  jsize len, jfloat *buf)
3868 {
3869         STATISTICS(jniinvokation());
3870
3871     if (start < 0 || len < 0 || start + len > array->header.size)
3872                 *exceptionptr =
3873                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3874
3875     else
3876                 MCOPY(buf, &array->data[start], jfloat, len);
3877 }
3878
3879
3880 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3881                                                   jsize len, jdouble *buf)
3882 {
3883         STATISTICS(jniinvokation());
3884
3885     if (start < 0 || len < 0 || start+len>array->header.size)
3886                 *exceptionptr =
3887                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3888
3889     else
3890                 MCOPY(buf, &array->data[start], jdouble, len);
3891 }
3892
3893
3894 /*  Set<PrimitiveType>ArrayRegion **********************************************
3895
3896         A family of functions that copies back a region of a primitive
3897         array from a buffer.
3898
3899 *******************************************************************************/
3900
3901 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3902                                                    jsize len, jboolean *buf)
3903 {
3904         STATISTICS(jniinvokation());
3905
3906     if (start < 0 || len < 0 || start + len > array->header.size)
3907                 *exceptionptr =
3908                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3909
3910     else
3911                 MCOPY(&array->data[start], buf, jboolean, len);
3912 }
3913
3914
3915 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3916                                                 jbyte *buf)
3917 {
3918         STATISTICS(jniinvokation());
3919
3920     if (start < 0 || len < 0 || start + len > array->header.size)
3921                 *exceptionptr =
3922                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3923
3924     else
3925                 MCOPY(&array->data[start], buf, jbyte, len);
3926 }
3927
3928
3929 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3930                                                 jchar *buf)
3931 {
3932         STATISTICS(jniinvokation());
3933
3934     if (start < 0 || len < 0 || start + len > array->header.size)
3935                 *exceptionptr =
3936                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3937
3938     else
3939                 MCOPY(&array->data[start], buf, jchar, len);
3940
3941 }
3942
3943
3944 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3945                                                  jsize len, jshort *buf)
3946 {
3947         STATISTICS(jniinvokation());
3948
3949     if (start < 0 || len < 0 || start + len > array->header.size)
3950                 *exceptionptr =
3951                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3952
3953     else
3954                 MCOPY(&array->data[start], buf, jshort, len);
3955 }
3956
3957
3958 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3959                                            jint *buf)
3960 {
3961         STATISTICS(jniinvokation());
3962
3963     if (start < 0 || len < 0 || start + len > array->header.size)
3964                 *exceptionptr =
3965                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3966
3967     else
3968                 MCOPY(&array->data[start], buf, jint, len);
3969
3970 }
3971
3972
3973 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3974                                                 jlong *buf)
3975 {
3976         STATISTICS(jniinvokation());
3977
3978     if (start < 0 || len < 0 || start + len > array->header.size)
3979                 *exceptionptr =
3980                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3981
3982     else
3983                 MCOPY(&array->data[start], buf, jlong, len);
3984
3985 }
3986
3987
3988 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3989                                                  jsize len, jfloat *buf)
3990 {
3991         STATISTICS(jniinvokation());
3992
3993     if (start < 0 || len < 0 || start + len > array->header.size)
3994                 *exceptionptr =
3995                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3996
3997     else
3998                 MCOPY(&array->data[start], buf, jfloat, len);
3999
4000 }
4001
4002
4003 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
4004                                                   jsize len, jdouble *buf)
4005 {
4006         STATISTICS(jniinvokation());
4007
4008     if (start < 0 || len < 0 || start + len > array->header.size)
4009                 *exceptionptr =
4010                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
4011
4012     else
4013                 MCOPY(&array->data[start], buf, jdouble, len);
4014 }
4015
4016
4017 /* Registering Native Methods *************************************************/
4018
4019 /* RegisterNatives *************************************************************
4020
4021    Registers native methods with the class specified by the clazz
4022    argument. The methods parameter specifies an array of
4023    JNINativeMethod structures that contain the names, signatures, and
4024    function pointers of the native methods. The nMethods parameter
4025    specifies the number of native methods in the array.
4026
4027 *******************************************************************************/
4028
4029 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
4030                                          jint nMethods)
4031 {
4032         STATISTICS(jniinvokation());
4033
4034     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
4035
4036     return 0;
4037 }
4038
4039
4040 /* UnregisterNatives ***********************************************************
4041
4042    Unregisters native methods of a class. The class goes back to the
4043    state before it was linked or registered with its native method
4044    functions.
4045
4046    This function should not be used in normal native code. Instead, it
4047    provides special programs a way to reload and relink native
4048    libraries.
4049
4050 *******************************************************************************/
4051
4052 jint UnregisterNatives(JNIEnv *env, jclass clazz)
4053 {
4054         STATISTICS(jniinvokation());
4055
4056         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
4057
4058     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
4059
4060     return 0;
4061 }
4062
4063
4064 /* Monitor Operations *********************************************************/
4065
4066 /* MonitorEnter ****************************************************************
4067
4068    Enters the monitor associated with the underlying Java object
4069    referred to by obj.
4070
4071 *******************************************************************************/
4072
4073 jint MonitorEnter(JNIEnv *env, jobject obj)
4074 {
4075         STATISTICS(jniinvokation());
4076
4077         if (!obj) {
4078                 *exceptionptr = new_nullpointerexception();
4079                 return JNI_ERR;
4080         }
4081
4082 #if defined(USE_THREADS)
4083         builtin_monitorenter(obj);
4084 #endif
4085
4086         return JNI_OK;
4087 }
4088
4089
4090 /* MonitorExit *****************************************************************
4091
4092    The current thread must be the owner of the monitor associated with
4093    the underlying Java object referred to by obj. The thread
4094    decrements the counter indicating the number of times it has
4095    entered this monitor. If the value of the counter becomes zero, the
4096    current thread releases the monitor.
4097
4098 *******************************************************************************/
4099
4100 jint MonitorExit(JNIEnv *env, jobject obj)
4101 {
4102         STATISTICS(jniinvokation());
4103         if (!obj) {
4104                 *exceptionptr = new_nullpointerexception();
4105                 return JNI_ERR;
4106         }
4107
4108 #if defined(USE_THREADS)
4109         builtin_monitorexit(obj);
4110 #endif
4111
4112         return JNI_OK;
4113 }
4114
4115
4116 /* JavaVM Interface ***********************************************************/
4117
4118 /* GetJavaVM *******************************************************************
4119
4120    Returns the Java VM interface (used in the Invocation API)
4121    associated with the current thread. The result is placed at the
4122    location pointed to by the second argument, vm.
4123
4124 *******************************************************************************/
4125
4126 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
4127 {
4128         STATISTICS(jniinvokation());
4129
4130     *vm = &ptr_jvm;
4131
4132         return 0;
4133 }
4134
4135
4136 void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
4137 {
4138         STATISTICS(jniinvokation());
4139
4140         log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
4141 }
4142
4143
4144 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
4145 {
4146         STATISTICS(jniinvokation());
4147
4148         log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
4149 }
4150
4151
4152 /* GetPrimitiveArrayCritical ***************************************************
4153
4154    Obtain a direct pointer to array elements.
4155
4156 *******************************************************************************/
4157
4158 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
4159 {
4160         java_bytearray *ba;
4161         jbyte          *bp;
4162
4163         ba = (java_bytearray *) array;
4164
4165         /* do the same as Kaffe does */
4166
4167         bp = GetByteArrayElements(env, ba, isCopy);
4168
4169         return (void *) bp;
4170 }
4171
4172
4173 /* ReleasePrimitiveArrayCritical ***********************************************
4174
4175    No specific documentation.
4176
4177 *******************************************************************************/
4178
4179 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
4180                                                                    jint mode)
4181 {
4182         STATISTICS(jniinvokation());
4183
4184         /* do the same as Kaffe does */
4185
4186         ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
4187 }
4188
4189
4190 /* GetStringCritical ***********************************************************
4191
4192    The semantics of these two functions are similar to the existing
4193    Get/ReleaseStringChars functions.
4194
4195 *******************************************************************************/
4196
4197 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
4198 {
4199         STATISTICS(jniinvokation());
4200
4201         return GetStringChars(env, string, isCopy);
4202 }
4203
4204
4205 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
4206 {
4207         STATISTICS(jniinvokation());
4208
4209         ReleaseStringChars(env, string, cstring);
4210 }
4211
4212
4213 jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
4214 {
4215         STATISTICS(jniinvokation());
4216
4217         log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
4218
4219         return obj;
4220 }
4221
4222
4223 void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
4224 {
4225         STATISTICS(jniinvokation());
4226
4227         log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
4228 }
4229
4230
4231 /* NewGlobalRef ****************************************************************
4232
4233    Creates a new global reference to the object referred to by the obj
4234    argument.
4235
4236 *******************************************************************************/
4237     
4238 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4239 {
4240         java_lang_Integer *refcount;
4241         java_objectheader *newval;
4242
4243         STATISTICS(jniinvokation());
4244
4245 #if defined(USE_THREADS)
4246         builtin_monitorenter(*global_ref_table);
4247 #endif
4248         
4249         refcount = (java_lang_Integer *)
4250                 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4251
4252         if (refcount == NULL) {
4253                 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4254
4255                 if (newval == NULL) {
4256 #if defined(USE_THREADS)
4257                         builtin_monitorexit(*global_ref_table);
4258 #endif
4259                         return NULL;
4260                 }
4261
4262                 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4263
4264         } else {
4265                 /* we can access the object itself, as we are in a
4266            synchronized section */
4267
4268                 refcount->value++;
4269         }
4270
4271 #if defined(USE_THREADS)
4272         builtin_monitorexit(*global_ref_table);
4273 #endif
4274
4275         return lobj;
4276 }
4277
4278
4279 /* DeleteGlobalRef *************************************************************
4280
4281    Deletes the global reference pointed to by globalRef.
4282
4283 *******************************************************************************/
4284
4285 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4286 {
4287         java_lang_Integer *refcount;
4288         s4                 val;
4289
4290         STATISTICS(jniinvokation());
4291
4292 #if defined(USE_THREADS)
4293         builtin_monitorenter(*global_ref_table);
4294 #endif
4295
4296         refcount = (java_lang_Integer *)
4297                 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4298
4299         if (refcount == NULL) {
4300                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4301                 return;
4302         }
4303
4304         /* we can access the object itself, as we are in a synchronized
4305            section */
4306
4307         val = refcount->value - 1;
4308
4309         if (val == 0) {
4310                 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4311                                                          NULL);
4312
4313         } else {
4314                 /* we do not create a new object, but set the new value into
4315            the old one */
4316
4317                 refcount->value = val;
4318         }
4319
4320 #if defined(USE_THREADS)
4321         builtin_monitorexit(*global_ref_table);
4322 #endif
4323 }
4324
4325
4326 /* ExceptionCheck **************************************************************
4327
4328    Returns JNI_TRUE when there is a pending exception; otherwise,
4329    returns JNI_FALSE.
4330
4331 *******************************************************************************/
4332
4333 jboolean ExceptionCheck(JNIEnv *env)
4334 {
4335         STATISTICS(jniinvokation());
4336
4337         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4338 }
4339
4340
4341 /* New JNI 1.4 functions ******************************************************/
4342
4343 /* NewDirectByteBuffer *********************************************************
4344
4345    Allocates and returns a direct java.nio.ByteBuffer referring to the
4346    block of memory starting at the memory address address and
4347    extending capacity bytes.
4348
4349 *******************************************************************************/
4350
4351 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4352 {
4353         java_objectheader *nbuf;
4354 #if SIZEOF_VOID_P == 8
4355         gnu_classpath_Pointer64 *paddress;
4356 #else
4357         gnu_classpath_Pointer32 *paddress;
4358 #endif
4359
4360         STATISTICS(jniinvokation());
4361
4362         log_text("JNI-NewDirectByteBuffer: called");
4363
4364 #if 0
4365         /* allocate a java.nio.DirectByteBufferImpl$ReadWrite object */
4366
4367         if (!(nbuf = (java_nio_DirectByteBufferImpl$ReadWrite *)
4368                   builtin_new(class_java_nio_DirectByteBufferImpl_ReadWrite)))
4369                 return NULL;
4370 #endif
4371
4372         /* alocate a gnu.classpath.Pointer{32,64} object */
4373
4374 #if SIZEOF_VOID_P == 8
4375         if (!(paddress = (gnu_classpath_Pointer64 *)
4376                   builtin_new(class_gnu_classpath_Pointer64)))
4377 #else
4378         if (!(paddress = (gnu_classpath_Pointer32 *)
4379                   builtin_new(class_gnu_classpath_Pointer32)))
4380 #endif
4381                 return NULL;
4382
4383         /* fill gnu.classpath.Pointer{32,64} with address */
4384
4385         paddress->data = (ptrint) address;
4386
4387 #if 0
4388         /* fill java.nio.Buffer object */
4389
4390         nbuf->cap     = (s4) capacity;
4391         nbuf->limit   = (s4) capacity;
4392         nbuf->pos     = 0;
4393         nbuf->address = (gnu_classpath_Pointer *) paddress;
4394 #endif
4395
4396         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
4397                                                          dbbirw_init, NULL, paddress,
4398                                                          (jint) capacity, (jint) capacity, (jint) 0);
4399
4400         /* add local reference and return the value */
4401
4402         return NewLocalRef(env, nbuf);
4403 }
4404
4405
4406 /* GetDirectBufferAddress ******************************************************
4407
4408    Fetches and returns the starting address of the memory region
4409    referenced by the given direct java.nio.Buffer.
4410
4411 *******************************************************************************/
4412
4413 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4414 {
4415         java_nio_DirectByteBufferImpl *nbuf;
4416 #if SIZEOF_VOID_P == 8
4417         gnu_classpath_Pointer64       *address;
4418 #else
4419         gnu_classpath_Pointer32       *address;
4420 #endif
4421
4422         STATISTICS(jniinvokation());
4423
4424 #if 0
4425         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4426                 return NULL;
4427 #endif
4428
4429         nbuf = (java_nio_DirectByteBufferImpl *) buf;
4430
4431 #if SIZEOF_VOID_P == 8
4432         address = (gnu_classpath_Pointer64 *) nbuf->address;
4433 #else
4434         address = (gnu_classpath_Pointer32 *) nbuf->address;
4435 #endif
4436
4437         return (void *) address->data;
4438 }
4439
4440
4441 /* GetDirectBufferCapacity *****************************************************
4442
4443    Fetches and returns the capacity in bytes of the memory region
4444    referenced by the given direct java.nio.Buffer.
4445
4446 *******************************************************************************/
4447
4448 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4449 {
4450         java_nio_Buffer *nbuf;
4451
4452         STATISTICS(jniinvokation());
4453
4454         if (buf == NULL)
4455                 return -1;
4456
4457         nbuf = (java_nio_Buffer *) buf;
4458
4459         return (jlong) nbuf->cap;
4460 }
4461
4462
4463 jint DestroyJavaVM(JavaVM *vm)
4464 {
4465         STATISTICS(jniinvokation());
4466
4467         log_text("JNI-Call: DestroyJavaVM: IMPLEMENT ME!");
4468
4469         return 0;
4470 }
4471
4472
4473 /* AttachCurrentThread *********************************************************
4474
4475    Attaches the current thread to a Java VM. Returns a JNI interface
4476    pointer in the JNIEnv argument.
4477
4478    Trying to attach a thread that is already attached is a no-op.
4479
4480    A native thread cannot be attached simultaneously to two Java VMs.
4481
4482    When a thread is attached to the VM, the context class loader is
4483    the bootstrap loader.
4484
4485 *******************************************************************************/
4486
4487 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4488 {
4489         STATISTICS(jniinvokation());
4490
4491         log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
4492
4493 #if !defined(HAVE___THREAD)
4494 /*      cacao_thread_attach();*/
4495 #else
4496         #error "No idea how to implement that. Perhaps Stefan knows"
4497 #endif
4498
4499         *env = &ptr_env;
4500
4501         return 0;
4502 }
4503
4504
4505 jint DetachCurrentThread(JavaVM *vm)
4506 {
4507         STATISTICS(jniinvokation());
4508
4509         log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
4510
4511         return 0;
4512 }
4513
4514
4515 /* GetEnv **********************************************************************
4516
4517    If the current thread is not attached to the VM, sets *env to NULL,
4518    and returns JNI_EDETACHED. If the specified version is not
4519    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4520    sets *env to the appropriate interface, and returns JNI_OK.
4521
4522 *******************************************************************************/
4523
4524 jint GetEnv(JavaVM *vm, void **env, jint version)
4525 {
4526         STATISTICS(jniinvokation());
4527
4528 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4529         if (thread_getself() == NULL) {
4530                 *env = NULL;
4531
4532                 return JNI_EDETACHED;
4533         }
4534 #endif
4535
4536         if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4537                 (version == JNI_VERSION_1_4)) {
4538                 *env = &ptr_env;
4539
4540                 return JNI_OK;
4541         }
4542
4543 #if defined(ENABLE_JVMTI)
4544         if (version == JVMTI_VERSION_1_0) {
4545                 *env = (void *) new_jvmtienv();
4546
4547                 if (env != NULL)
4548                         return JNI_OK;
4549         }
4550 #endif
4551         
4552         *env = NULL;
4553
4554         return JNI_EVERSION;
4555 }
4556
4557
4558
4559 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4560 {
4561         STATISTICS(jniinvokation());
4562
4563         log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
4564
4565         return 0;
4566 }
4567
4568
4569 /* JNI invocation table *******************************************************/
4570
4571 const struct JNIInvokeInterface JNI_JavaVMTable = {
4572         NULL,
4573         NULL,
4574         NULL,
4575
4576         DestroyJavaVM,
4577         AttachCurrentThread,
4578         DetachCurrentThread,
4579         GetEnv,
4580         AttachCurrentThreadAsDaemon
4581 };
4582
4583
4584 /* JNI function table *********************************************************/
4585
4586 struct JNINativeInterface JNI_JNIEnvTable = {
4587         NULL,
4588         NULL,
4589         NULL,
4590         NULL,    
4591         &GetVersion,
4592
4593         &DefineClass,
4594         &FindClass,
4595         &FromReflectedMethod,
4596         &FromReflectedField,
4597         &ToReflectedMethod,
4598         &GetSuperclass,
4599         &IsAssignableFrom,
4600         &ToReflectedField,
4601
4602         &Throw,
4603         &ThrowNew,
4604         &ExceptionOccurred,
4605         &ExceptionDescribe,
4606         &ExceptionClear,
4607         &FatalError,
4608         &PushLocalFrame,
4609         &PopLocalFrame,
4610
4611         &NewGlobalRef,
4612         &DeleteGlobalRef,
4613         &DeleteLocalRef,
4614         &IsSameObject,
4615         &NewLocalRef,
4616         &EnsureLocalCapacity,
4617
4618         &AllocObject,
4619         &NewObject,
4620         &NewObjectV,
4621         &NewObjectA,
4622
4623         &GetObjectClass,
4624         &IsInstanceOf,
4625
4626         &GetMethodID,
4627
4628         &CallObjectMethod,
4629         &CallObjectMethodV,
4630         &CallObjectMethodA,
4631         &CallBooleanMethod,
4632         &CallBooleanMethodV,
4633         &CallBooleanMethodA,
4634         &CallByteMethod,
4635         &CallByteMethodV,
4636         &CallByteMethodA,
4637         &CallCharMethod,
4638         &CallCharMethodV,
4639         &CallCharMethodA,
4640         &CallShortMethod,
4641         &CallShortMethodV,
4642         &CallShortMethodA,
4643         &CallIntMethod,
4644         &CallIntMethodV,
4645         &CallIntMethodA,
4646         &CallLongMethod,
4647         &CallLongMethodV,
4648         &CallLongMethodA,
4649         &CallFloatMethod,
4650         &CallFloatMethodV,
4651         &CallFloatMethodA,
4652         &CallDoubleMethod,
4653         &CallDoubleMethodV,
4654         &CallDoubleMethodA,
4655         &CallVoidMethod,
4656         &CallVoidMethodV,
4657         &CallVoidMethodA,
4658
4659         &CallNonvirtualObjectMethod,
4660         &CallNonvirtualObjectMethodV,
4661         &CallNonvirtualObjectMethodA,
4662         &CallNonvirtualBooleanMethod,
4663         &CallNonvirtualBooleanMethodV,
4664         &CallNonvirtualBooleanMethodA,
4665         &CallNonvirtualByteMethod,
4666         &CallNonvirtualByteMethodV,
4667         &CallNonvirtualByteMethodA,
4668         &CallNonvirtualCharMethod,
4669         &CallNonvirtualCharMethodV,
4670         &CallNonvirtualCharMethodA,
4671         &CallNonvirtualShortMethod,
4672         &CallNonvirtualShortMethodV,
4673         &CallNonvirtualShortMethodA,
4674         &CallNonvirtualIntMethod,
4675         &CallNonvirtualIntMethodV,
4676         &CallNonvirtualIntMethodA,
4677         &CallNonvirtualLongMethod,
4678         &CallNonvirtualLongMethodV,
4679         &CallNonvirtualLongMethodA,
4680         &CallNonvirtualFloatMethod,
4681         &CallNonvirtualFloatMethodV,
4682         &CallNonvirtualFloatMethodA,
4683         &CallNonvirtualDoubleMethod,
4684         &CallNonvirtualDoubleMethodV,
4685         &CallNonvirtualDoubleMethodA,
4686         &CallNonvirtualVoidMethod,
4687         &CallNonvirtualVoidMethodV,
4688         &CallNonvirtualVoidMethodA,
4689
4690         &GetFieldID,
4691
4692         &GetObjectField,
4693         &GetBooleanField,
4694         &GetByteField,
4695         &GetCharField,
4696         &GetShortField,
4697         &GetIntField,
4698         &GetLongField,
4699         &GetFloatField,
4700         &GetDoubleField,
4701         &SetObjectField,
4702         &SetBooleanField,
4703         &SetByteField,
4704         &SetCharField,
4705         &SetShortField,
4706         &SetIntField,
4707         &SetLongField,
4708         &SetFloatField,
4709         &SetDoubleField,
4710
4711         &GetStaticMethodID,
4712
4713         &CallStaticObjectMethod,
4714         &CallStaticObjectMethodV,
4715         &CallStaticObjectMethodA,
4716         &CallStaticBooleanMethod,
4717         &CallStaticBooleanMethodV,
4718         &CallStaticBooleanMethodA,
4719         &CallStaticByteMethod,
4720         &CallStaticByteMethodV,
4721         &CallStaticByteMethodA,
4722         &CallStaticCharMethod,
4723         &CallStaticCharMethodV,
4724         &CallStaticCharMethodA,
4725         &CallStaticShortMethod,
4726         &CallStaticShortMethodV,
4727         &CallStaticShortMethodA,
4728         &CallStaticIntMethod,
4729         &CallStaticIntMethodV,
4730         &CallStaticIntMethodA,
4731         &CallStaticLongMethod,
4732         &CallStaticLongMethodV,
4733         &CallStaticLongMethodA,
4734         &CallStaticFloatMethod,
4735         &CallStaticFloatMethodV,
4736         &CallStaticFloatMethodA,
4737         &CallStaticDoubleMethod,
4738         &CallStaticDoubleMethodV,
4739         &CallStaticDoubleMethodA,
4740         &CallStaticVoidMethod,
4741         &CallStaticVoidMethodV,
4742         &CallStaticVoidMethodA,
4743
4744         &GetStaticFieldID,
4745
4746         &GetStaticObjectField,
4747         &GetStaticBooleanField,
4748         &GetStaticByteField,
4749         &GetStaticCharField,
4750         &GetStaticShortField,
4751         &GetStaticIntField,
4752         &GetStaticLongField,
4753         &GetStaticFloatField,
4754         &GetStaticDoubleField,
4755         &SetStaticObjectField,
4756         &SetStaticBooleanField,
4757         &SetStaticByteField,
4758         &SetStaticCharField,
4759         &SetStaticShortField,
4760         &SetStaticIntField,
4761         &SetStaticLongField,
4762         &SetStaticFloatField,
4763         &SetStaticDoubleField,
4764
4765         &NewString,
4766         &GetStringLength,
4767         &GetStringChars,
4768         &ReleaseStringChars,
4769
4770         &NewStringUTF,
4771         &GetStringUTFLength,
4772         &GetStringUTFChars,
4773         &ReleaseStringUTFChars,
4774
4775         &GetArrayLength,
4776
4777         &NewObjectArray,
4778         &GetObjectArrayElement,
4779         &SetObjectArrayElement,
4780
4781         &NewBooleanArray,
4782         &NewByteArray,
4783         &NewCharArray,
4784         &NewShortArray,
4785         &NewIntArray,
4786         &NewLongArray,
4787         &NewFloatArray,
4788         &NewDoubleArray,
4789
4790         &GetBooleanArrayElements,
4791         &GetByteArrayElements,
4792         &GetCharArrayElements,
4793         &GetShortArrayElements,
4794         &GetIntArrayElements,
4795         &GetLongArrayElements,
4796         &GetFloatArrayElements,
4797         &GetDoubleArrayElements,
4798
4799         &ReleaseBooleanArrayElements,
4800         &ReleaseByteArrayElements,
4801         &ReleaseCharArrayElements,
4802         &ReleaseShortArrayElements,
4803         &ReleaseIntArrayElements,
4804         &ReleaseLongArrayElements,
4805         &ReleaseFloatArrayElements,
4806         &ReleaseDoubleArrayElements,
4807
4808         &GetBooleanArrayRegion,
4809         &GetByteArrayRegion,
4810         &GetCharArrayRegion,
4811         &GetShortArrayRegion,
4812         &GetIntArrayRegion,
4813         &GetLongArrayRegion,
4814         &GetFloatArrayRegion,
4815         &GetDoubleArrayRegion,
4816         &SetBooleanArrayRegion,
4817         &SetByteArrayRegion,
4818         &SetCharArrayRegion,
4819         &SetShortArrayRegion,
4820         &SetIntArrayRegion,
4821         &SetLongArrayRegion,
4822         &SetFloatArrayRegion,
4823         &SetDoubleArrayRegion,
4824
4825         &RegisterNatives,
4826         &UnregisterNatives,
4827
4828         &MonitorEnter,
4829         &MonitorExit,
4830
4831         &GetJavaVM,
4832
4833         /* new JNI 1.2 functions */
4834
4835         &GetStringRegion,
4836         &GetStringUTFRegion,
4837
4838         &GetPrimitiveArrayCritical,
4839         &ReleasePrimitiveArrayCritical,
4840
4841         &GetStringCritical,
4842         &ReleaseStringCritical,
4843
4844         &NewWeakGlobalRef,
4845         &DeleteWeakGlobalRef,
4846
4847         &ExceptionCheck,
4848
4849         /* new JNI 1.4 functions */
4850
4851         &NewDirectByteBuffer,
4852         &GetDirectBufferAddress,
4853         &GetDirectBufferCapacity
4854 };
4855
4856
4857 /* Invocation API Functions ***************************************************/
4858
4859 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4860
4861    Returns a default configuration for the Java VM.
4862
4863 *******************************************************************************/
4864
4865 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4866 {
4867         JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4868
4869         /* GNU classpath currently supports JNI 1.2 */
4870
4871         _vm_args->version = JNI_VERSION_1_2;
4872
4873         return 0;
4874 }
4875
4876
4877 /* JNI_GetCreatedJavaVMs *******************************************************
4878
4879    Returns all Java VMs that have been created. Pointers to VMs are written in
4880    the buffer vmBuf in the order they are created. At most bufLen number of
4881    entries will be written. The total number of created VMs is returned in
4882    *nVMs.
4883
4884 *******************************************************************************/
4885
4886 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4887 {
4888         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4889
4890         return 0;
4891 }
4892
4893
4894 /* JNI_CreateJavaVM ************************************************************
4895
4896    Loads and initializes a Java VM. The current thread becomes the main thread.
4897    Sets the env argument to the JNI interface pointer of the main thread.
4898
4899 *******************************************************************************/
4900
4901 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4902 {
4903         const struct JNIInvokeInterface *vm;
4904         struct JNINativeInterface *env;
4905
4906         vm = &JNI_JavaVMTable;
4907         env = &JNI_JNIEnvTable;
4908
4909         *p_vm = (JavaVM *) vm;
4910         *p_env = (JNIEnv *) env;
4911
4912         return 0;
4913 }
4914
4915
4916 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4917                                                                            jobject obj, java_objectarray *params)
4918 {
4919         jni_callblock *blk;
4920         jobject        o;
4921         s4             argcount;
4922         s4             paramcount;
4923
4924         if (methodID == 0) {
4925                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
4926                 return NULL;
4927         }
4928
4929         argcount = methodID->parseddesc->paramcount;
4930         paramcount = argcount;
4931
4932         /* if method is non-static, remove the `this' pointer */
4933
4934         if (!(methodID->flags & ACC_STATIC))
4935                 paramcount--;
4936
4937         /* the method is an instance method the obj has to be an instance of the 
4938            class the method belongs to. For static methods the obj parameter
4939            is ignored. */
4940
4941         if (!(methodID->flags & ACC_STATIC) && obj &&
4942                 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4943                 *exceptionptr =
4944                         new_exception_message(string_java_lang_IllegalArgumentException,
4945                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4946                 return NULL;
4947         }
4948
4949         if (((params == NULL) && (paramcount != 0)) ||
4950                 (params && (params->header.size != paramcount))) {
4951                 *exceptionptr =
4952                         new_exception(string_java_lang_IllegalArgumentException);
4953                 return NULL;
4954         }
4955
4956
4957         if (!(methodID->flags & ACC_STATIC) && !obj)  {
4958                 *exceptionptr =
4959                         new_exception_message(string_java_lang_NullPointerException,
4960                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4961                 return NULL;
4962         }
4963
4964         if ((methodID->flags & ACC_STATIC) && (obj))
4965                 obj = NULL;
4966
4967         if (obj) {
4968                 if ((methodID->flags & ACC_ABSTRACT) ||
4969                         (methodID->class->flags & ACC_INTERFACE)) {
4970                         methodID = get_virtual(obj, methodID);
4971                 }
4972         }
4973
4974         blk = MNEW(jni_callblock, argcount);
4975
4976         if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4977                                                                                  params))
4978                 return NULL;
4979
4980         switch (methodID->parseddesc->returntype.decltype) {
4981         case TYPE_VOID:
4982                 (void) asm_calljavafunction2(methodID, argcount,
4983                                                                          argcount * sizeof(jni_callblock),
4984                                                                          blk);
4985                 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4986                 break;
4987
4988         case PRIMITIVETYPE_INT: {
4989                 s4 i;
4990                 i = asm_calljavafunction2int(methodID, argcount,
4991                                                                          argcount * sizeof(jni_callblock),
4992                                                                          blk);
4993
4994                 o = native_new_and_init_int(class_java_lang_Integer, i);
4995         }
4996         break;
4997
4998         case PRIMITIVETYPE_BYTE: {
4999                 s4 i;
5000                 i = asm_calljavafunction2int(methodID, argcount,
5001                                                                          argcount * sizeof(jni_callblock),
5002                                                                          blk);
5003
5004 /*              o = native_new_and_init_int(class_java_lang_Byte, i); */
5005                 o = builtin_new(class_java_lang_Byte);
5006                 CallVoidMethod(env,
5007                                            o,
5008                                            class_resolvemethod(o->vftbl->class,
5009                                                                                    utf_init,
5010                                                                                    utf_byte__void),
5011                                            i);
5012         }
5013         break;
5014
5015         case PRIMITIVETYPE_CHAR: {
5016                 s4 intVal;
5017                 intVal = asm_calljavafunction2int(methodID,
5018                                                                                   argcount,
5019                                                                                   argcount * sizeof(jni_callblock),
5020                                                                                   blk);
5021                 o = builtin_new(class_java_lang_Character);
5022                 CallVoidMethod(env,
5023                                            o,
5024                                            class_resolvemethod(o->vftbl->class,
5025                                                                                    utf_init,
5026                                                                                    utf_char__void),
5027                                            intVal);
5028         }
5029         break;
5030
5031         case PRIMITIVETYPE_SHORT: {
5032                 s4 intVal;
5033                 intVal = asm_calljavafunction2int(methodID,
5034                                                                                   argcount,
5035                                                                                   argcount * sizeof(jni_callblock),
5036                                                                                   blk);
5037                 o = builtin_new(class_java_lang_Short);
5038                 CallVoidMethod(env,
5039                                            o,
5040                                            class_resolvemethod(o->vftbl->class,
5041                                                                                    utf_init,
5042                                                                                    utf_short__void),
5043                                            intVal);
5044         }
5045         break;
5046
5047         case PRIMITIVETYPE_BOOLEAN: {
5048                 s4 intVal;
5049                 intVal = asm_calljavafunction2int(methodID,
5050                                                                                   argcount,
5051                                                                                   argcount * sizeof(jni_callblock),
5052                                                                                   blk);
5053                 o = builtin_new(class_java_lang_Boolean);
5054                 CallVoidMethod(env,
5055                                            o,
5056                                            class_resolvemethod(o->vftbl->class,
5057                                                                                    utf_init,
5058                                                                                    utf_boolean__void),
5059                                            intVal);
5060         }
5061         break;
5062
5063         case PRIMITIVETYPE_LONG: {
5064                 jlong longVal;
5065                 longVal = asm_calljavafunction2long(methodID,
5066                                                                                         argcount,
5067                                                                                         argcount * sizeof(jni_callblock),
5068                                                                                         blk);
5069                 o = builtin_new(class_java_lang_Long);
5070                 CallVoidMethod(env,
5071                                            o,
5072                                            class_resolvemethod(o->vftbl->class,
5073                                                                                    utf_init,
5074                                                                                    utf_long__void),
5075                                            longVal);
5076         }
5077         break;
5078
5079         case PRIMITIVETYPE_FLOAT: {
5080                 jdouble floatVal;       
5081                 floatVal = asm_calljavafunction2float(methodID,
5082                                                                                           argcount,
5083                                                                                           argcount * sizeof(jni_callblock),
5084                                                                                           blk);
5085                 o = builtin_new(class_java_lang_Float);
5086                 CallVoidMethod(env,
5087                                            o,
5088                                            class_resolvemethod(o->vftbl->class,
5089                                                                                    utf_init,
5090                                                                                    utf_float__void),
5091                                            floatVal);
5092         }
5093         break;
5094
5095         case PRIMITIVETYPE_DOUBLE: {
5096                 jdouble doubleVal;
5097                 doubleVal = asm_calljavafunction2double(methodID,
5098                                                                                                 argcount,
5099                                                                                                 argcount * sizeof(jni_callblock),
5100                                                                                                 blk);
5101                 o = builtin_new(class_java_lang_Double);
5102                 CallVoidMethod(env,
5103                                            o,
5104                                            class_resolvemethod(o->vftbl->class,
5105                                                                                    utf_init,
5106                                                                                    utf_double__void),
5107                                            doubleVal);
5108         }
5109         break;
5110
5111         case TYPE_ADR:
5112                 o = asm_calljavafunction2(methodID, argcount,
5113                                                                   argcount * sizeof(jni_callblock), blk);
5114                 break;
5115
5116         default:
5117                 /* if this happens the exception has already been set by              */
5118                 /* fill_callblock_from_objectarray                                    */
5119
5120                 MFREE(blk, jni_callblock, argcount);
5121                 return (jobject *) 0;
5122         }
5123
5124         MFREE(blk, jni_callblock, argcount);
5125
5126         if (*exceptionptr) {
5127                 java_objectheader *cause;
5128
5129                 cause = *exceptionptr;
5130
5131                 /* clear exception pointer, we are calling JIT code again */
5132
5133                 *exceptionptr = NULL;
5134
5135                 *exceptionptr =
5136                         new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
5137                                                                         (java_lang_Throwable *) cause);
5138         }
5139
5140         return (jobject *) o;
5141 }
5142
5143
5144 /*
5145  * These are local overrides for various environment variables in Emacs.
5146  * Please do not remove this and leave it at the end of the file, where
5147  * Emacs will automagically detect them.
5148  * ---------------------------------------------------------------------
5149  * Local variables:
5150  * mode: c
5151  * indent-tabs-mode: t
5152  * c-basic-offset: 4
5153  * tab-width: 4
5154  * End:
5155  */