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