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