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