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