* GetEnv: call thread_getself, but i don't know if this is correct
[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 2898 2005-07-04 20:40:55Z twisti $
35
36 */
37
38
39 #include <assert.h>
40 #include <string.h>
41
42 #include "config.h"
43 #include "mm/boehm.h"
44 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Object.h"
48 #include "native/include/java_lang_Byte.h"
49 #include "native/include/java_lang_Character.h"
50 #include "native/include/java_lang_Short.h"
51 #include "native/include/java_lang_Integer.h"
52 #include "native/include/java_lang_Boolean.h"
53 #include "native/include/java_lang_Long.h"
54 #include "native/include/java_lang_Float.h"
55 #include "native/include/java_lang_Double.h"
56 #include "native/include/java_lang_Throwable.h"
57 #include "native/include/java_lang_reflect_Method.h"
58 #include "native/include/java_lang_reflect_Constructor.h"
59 #include "native/include/java_lang_reflect_Field.h"
60
61 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
62 #include "native/include/java_lang_VMClass.h"
63 #include "native/include/java_lang_VMClassLoader.h"
64
65 #if defined(USE_THREADS)
66 # if defined(NATIVE_THREADS)
67 #  include "threads/native/threads.h"
68 # else
69 #  include "threads/green/threads.h"
70 # endif
71 #endif
72
73 #include "toolbox/logging.h"
74 #include "vm/builtin.h"
75 #include "vm/exceptions.h"
76 #include "vm/global.h"
77 #include "vm/initialize.h"
78 #include "vm/loader.h"
79 #include "vm/options.h"
80 #include "vm/resolve.h"
81 #include "vm/statistics.h"
82 #include "vm/stringlocal.h"
83 #include "vm/tables.h"
84 #include "vm/jit/asmpart.h"
85 #include "vm/jit/jit.h"
86 #include "vm/statistics.h"
87
88
89 /* XXX TWISTI hack: define it extern so they can be found in this file */
90 extern const struct JNIInvokeInterface JNI_JavaVMTable;
91 extern struct JNINativeInterface JNI_JNIEnvTable;
92
93 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
94 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
95 static void* ptr_env = (void*) &JNI_JNIEnvTable;
96
97
98 #define PTR_TO_ITEM(ptr)   ((u8)(size_t)(ptr))
99
100 /* global reference table */
101 static jobject *global_ref_table;
102 static bool initrunning=false;
103
104 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
105 static jmethodID getmid = NULL;
106 static jmethodID putmid = NULL;
107 static jclass intclass = NULL;
108 static jmethodID intvalue = NULL;
109 static jmethodID newint = NULL;
110 static jclass ihmclass = NULL;
111 static jmethodID removemid = NULL;
112
113 #define JWCLINITDEBUG(x)
114
115
116 /********************* accessing instance-fields **********************************/
117
118 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;  
119 #define getField(obj,typ,var)     *((typ*) ((long int) obj + (long int) var->offset))
120 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
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 (thread_getself() == NULL) {
3686                 *env = NULL;
3687                 return JNI_EDETACHED;
3688         }
3689
3690         if ((version != JNI_VERSION_1_1) && (version != JNI_VERSION_1_2) &&
3691                 (version != JNI_VERSION_1_4)) {
3692                 *env = NULL;
3693                 return JNI_EVERSION;
3694         }
3695
3696         *env = &ptr_env;
3697
3698         return JNI_OK;
3699 }
3700
3701
3702 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3703 {
3704         STATS(jniinvokation();)
3705         log_text("AttachCurrentThreadAsDaemon called");
3706
3707         return 0;
3708 }
3709
3710 /************* JNI Initialization ****************************************************/
3711
3712 jobject jni_init1(JNIEnv* env, jobject lobj) {
3713 #if defined(USE_THREADS)
3714         while (initrunning) {yieldThread();} /* wait until init is done */
3715 #endif
3716         if (global_ref_table == NULL) {
3717                 jni_init();
3718         } 
3719 #if defined(USE_THREADS)
3720         else {
3721                 /* wait until jni_init is done */
3722                 MonitorEnter(env, *global_ref_table) ;
3723                 MonitorExit(env, *global_ref_table);
3724         }
3725 #endif
3726         return NewGlobalRef(env, lobj); 
3727 }
3728 void jni_init2(JNIEnv* env, jobject gref) {
3729         log_text("DeleteGlobalref called before NewGlobalref");
3730 #if defined(USE_THREADS)
3731         while (initrunning) {yieldThread();} /* wait until init is done */
3732 #endif
3733         if (global_ref_table == NULL) {
3734                 jni_init();
3735         } 
3736 #if defined(USE_THREADS)
3737         else {
3738                 /* wait until jni_init is done */
3739                 MonitorEnter(env, *global_ref_table) ;
3740                 MonitorExit(env, *global_ref_table);
3741         }
3742 #endif
3743         DeleteGlobalRef(env, gref); 
3744 }
3745
3746 void jni_init(){
3747         jmethodID mid;
3748
3749         initrunning = true;
3750         log_text("JNI-Init: initialize global_ref_table");
3751         /* initalize global reference table */
3752         ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3753         
3754         if (ihmclass == NULL) {
3755                 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3756         }
3757
3758         mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3759         if (mid == NULL) {
3760                 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3761         }
3762         
3763         global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3764
3765         *global_ref_table = NewObject(NULL,ihmclass,mid);
3766
3767         if (*global_ref_table == NULL) {
3768                 log_text("JNI-Init: unable to create new global_ref_table");
3769         }
3770
3771         initrunning = false;
3772
3773         getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3774         if (mid == NULL) {
3775                 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3776         }
3777
3778         getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3779         if (getmid == NULL) {
3780                 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3781         }
3782
3783         putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3784         if (putmid == NULL) {
3785                 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3786         }
3787
3788         intclass = FindClass(NULL, "java/lang/Integer");
3789         if (intclass == NULL) {
3790                 log_text("JNI-Init: unable to find java.lang.Integer");
3791         }
3792
3793         newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3794         if (newint == NULL) {
3795                 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3796         }
3797
3798         intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3799         if (intvalue == NULL) {
3800                 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3801         }
3802
3803         removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3804         if (removemid == NULL) {
3805                 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3806         }
3807         
3808         /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3809
3810         JNI_JNIEnvTable.NewGlobalRef = &NewGlobalRef;
3811         JNI_JNIEnvTable.DeleteGlobalRef = &DeleteGlobalRef;
3812 }
3813
3814
3815 /* JNI invocation table *******************************************************/
3816
3817 const struct JNIInvokeInterface JNI_JavaVMTable = {
3818         NULL,
3819         NULL,
3820         NULL,
3821
3822         DestroyJavaVM,
3823         AttachCurrentThread,
3824         DetachCurrentThread,
3825         GetEnv,
3826         AttachCurrentThreadAsDaemon
3827 };
3828
3829
3830 /* JNI function table *********************************************************/
3831
3832 struct JNINativeInterface JNI_JNIEnvTable = {
3833         NULL,
3834         NULL,
3835         NULL,
3836         NULL,    
3837         &GetVersion,
3838
3839         &DefineClass,
3840         &FindClass,
3841         &FromReflectedMethod,
3842         &FromReflectedField,
3843         &ToReflectedMethod,
3844         &GetSuperclass,
3845         &IsAssignableFrom,
3846         &ToReflectedField,
3847
3848         &Throw,
3849         &ThrowNew,
3850         &ExceptionOccurred,
3851         &ExceptionDescribe,
3852         &ExceptionClear,
3853         &FatalError,
3854         &PushLocalFrame,
3855         &PopLocalFrame,
3856
3857         &jni_init1, /* &NewGlobalRef,    initialize Global_Ref_Table*/
3858         &jni_init2, /* &DeleteGlobalRef,*/
3859         &DeleteLocalRef,
3860         &IsSameObject,
3861         &NewLocalRef,
3862         &EnsureLocalCapacity,
3863
3864         &AllocObject,
3865         &NewObject,
3866         &NewObjectV,
3867         &NewObjectA,
3868
3869         &GetObjectClass,
3870         &IsInstanceOf,
3871
3872         &GetMethodID,
3873
3874         &CallObjectMethod,
3875         &CallObjectMethodV,
3876         &CallObjectMethodA,
3877         &CallBooleanMethod,
3878         &CallBooleanMethodV,
3879         &CallBooleanMethodA,
3880         &CallByteMethod,
3881         &CallByteMethodV,
3882         &CallByteMethodA,
3883         &CallCharMethod,
3884         &CallCharMethodV,
3885         &CallCharMethodA,
3886         &CallShortMethod,
3887         &CallShortMethodV,
3888         &CallShortMethodA,
3889         &CallIntMethod,
3890         &CallIntMethodV,
3891         &CallIntMethodA,
3892         &CallLongMethod,
3893         &CallLongMethodV,
3894         &CallLongMethodA,
3895         &CallFloatMethod,
3896         &CallFloatMethodV,
3897         &CallFloatMethodA,
3898         &CallDoubleMethod,
3899         &CallDoubleMethodV,
3900         &CallDoubleMethodA,
3901         &CallVoidMethod,
3902         &CallVoidMethodV,
3903         &CallVoidMethodA,
3904
3905         &CallNonvirtualObjectMethod,
3906         &CallNonvirtualObjectMethodV,
3907         &CallNonvirtualObjectMethodA,
3908         &CallNonvirtualBooleanMethod,
3909         &CallNonvirtualBooleanMethodV,
3910         &CallNonvirtualBooleanMethodA,
3911         &CallNonvirtualByteMethod,
3912         &CallNonvirtualByteMethodV,
3913         &CallNonvirtualByteMethodA,
3914         &CallNonvirtualCharMethod,
3915         &CallNonvirtualCharMethodV,
3916         &CallNonvirtualCharMethodA,
3917         &CallNonvirtualShortMethod,
3918         &CallNonvirtualShortMethodV,
3919         &CallNonvirtualShortMethodA,
3920         &CallNonvirtualIntMethod,
3921         &CallNonvirtualIntMethodV,
3922         &CallNonvirtualIntMethodA,
3923         &CallNonvirtualLongMethod,
3924         &CallNonvirtualLongMethodV,
3925         &CallNonvirtualLongMethodA,
3926         &CallNonvirtualFloatMethod,
3927         &CallNonvirtualFloatMethodV,
3928         &CallNonvirtualFloatMethodA,
3929         &CallNonvirtualDoubleMethod,
3930         &CallNonvirtualDoubleMethodV,
3931         &CallNonvirtualDoubleMethodA,
3932         &CallNonvirtualVoidMethod,
3933         &CallNonvirtualVoidMethodV,
3934         &CallNonvirtualVoidMethodA,
3935
3936         &GetFieldID,
3937
3938         &GetObjectField,
3939         &GetBooleanField,
3940         &GetByteField,
3941         &GetCharField,
3942         &GetShortField,
3943         &GetIntField,
3944         &GetLongField,
3945         &GetFloatField,
3946         &GetDoubleField,
3947         &SetObjectField,
3948         &SetBooleanField,
3949         &SetByteField,
3950         &SetCharField,
3951         &SetShortField,
3952         &SetIntField,
3953         &SetLongField,
3954         &SetFloatField,
3955         &SetDoubleField,
3956
3957         &GetStaticMethodID,
3958
3959         &CallStaticObjectMethod,
3960         &CallStaticObjectMethodV,
3961         &CallStaticObjectMethodA,
3962         &CallStaticBooleanMethod,
3963         &CallStaticBooleanMethodV,
3964         &CallStaticBooleanMethodA,
3965         &CallStaticByteMethod,
3966         &CallStaticByteMethodV,
3967         &CallStaticByteMethodA,
3968         &CallStaticCharMethod,
3969         &CallStaticCharMethodV,
3970         &CallStaticCharMethodA,
3971         &CallStaticShortMethod,
3972         &CallStaticShortMethodV,
3973         &CallStaticShortMethodA,
3974         &CallStaticIntMethod,
3975         &CallStaticIntMethodV,
3976         &CallStaticIntMethodA,
3977         &CallStaticLongMethod,
3978         &CallStaticLongMethodV,
3979         &CallStaticLongMethodA,
3980         &CallStaticFloatMethod,
3981         &CallStaticFloatMethodV,
3982         &CallStaticFloatMethodA,
3983         &CallStaticDoubleMethod,
3984         &CallStaticDoubleMethodV,
3985         &CallStaticDoubleMethodA,
3986         &CallStaticVoidMethod,
3987         &CallStaticVoidMethodV,
3988         &CallStaticVoidMethodA,
3989
3990         &GetStaticFieldID,
3991
3992         &GetStaticObjectField,
3993         &GetStaticBooleanField,
3994         &GetStaticByteField,
3995         &GetStaticCharField,
3996         &GetStaticShortField,
3997         &GetStaticIntField,
3998         &GetStaticLongField,
3999         &GetStaticFloatField,
4000         &GetStaticDoubleField,
4001         &SetStaticObjectField,
4002         &SetStaticBooleanField,
4003         &SetStaticByteField,
4004         &SetStaticCharField,
4005         &SetStaticShortField,
4006         &SetStaticIntField,
4007         &SetStaticLongField,
4008         &SetStaticFloatField,
4009         &SetStaticDoubleField,
4010
4011         &NewString,
4012         &GetStringLength,
4013         &GetStringChars,
4014         &ReleaseStringChars,
4015
4016         &NewStringUTF,
4017         &GetStringUTFLength,
4018         &GetStringUTFChars,
4019         &ReleaseStringUTFChars,
4020
4021         &GetArrayLength,
4022
4023         &NewObjectArray,
4024         &GetObjectArrayElement,
4025         &SetObjectArrayElement,
4026
4027         &NewBooleanArray,
4028         &NewByteArray,
4029         &NewCharArray,
4030         &NewShortArray,
4031         &NewIntArray,
4032         &NewLongArray,
4033         &NewFloatArray,
4034         &NewDoubleArray,
4035
4036         &GetBooleanArrayElements,
4037         &GetByteArrayElements,
4038         &GetCharArrayElements,
4039         &GetShortArrayElements,
4040         &GetIntArrayElements,
4041         &GetLongArrayElements,
4042         &GetFloatArrayElements,
4043         &GetDoubleArrayElements,
4044
4045         &ReleaseBooleanArrayElements,
4046         &ReleaseByteArrayElements,
4047         &ReleaseCharArrayElements,
4048         &ReleaseShortArrayElements,
4049         &ReleaseIntArrayElements,
4050         &ReleaseLongArrayElements,
4051         &ReleaseFloatArrayElements,
4052         &ReleaseDoubleArrayElements,
4053
4054         &GetBooleanArrayRegion,
4055         &GetByteArrayRegion,
4056         &GetCharArrayRegion,
4057         &GetShortArrayRegion,
4058         &GetIntArrayRegion,
4059         &GetLongArrayRegion,
4060         &GetFloatArrayRegion,
4061         &GetDoubleArrayRegion,
4062         &SetBooleanArrayRegion,
4063         &SetByteArrayRegion,
4064         &SetCharArrayRegion,
4065         &SetShortArrayRegion,
4066         &SetIntArrayRegion,
4067         &SetLongArrayRegion,
4068         &SetFloatArrayRegion,
4069         &SetDoubleArrayRegion,
4070
4071         &RegisterNatives,
4072         &UnregisterNatives,
4073
4074         &MonitorEnter,
4075         &MonitorExit,
4076
4077         &GetJavaVM,
4078
4079         /* new JNI 1.2 functions */
4080
4081         &GetStringRegion,
4082         &GetStringUTFRegion,
4083
4084         &GetPrimitiveArrayCritical,
4085         &ReleasePrimitiveArrayCritical,
4086
4087         &GetStringCritical,
4088         &ReleaseStringCritical,
4089
4090         &NewWeakGlobalRef,
4091         &DeleteWeakGlobalRef,
4092
4093         &ExceptionCheck,
4094
4095         /* new JNI 1.4 functions */
4096
4097         &NewDirectByteBuffer,
4098         &GetDirectBufferAddress,
4099         &GetDirectBufferCapacity
4100 };
4101
4102
4103 /* Invocation API Functions ***************************************************/
4104
4105 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4106
4107    Returns a default configuration for the Java VM.
4108
4109 *******************************************************************************/
4110
4111 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4112 {
4113         JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4114
4115         /* GNU classpath currently supports JNI 1.2 */
4116
4117         _vm_args->version = JNI_VERSION_1_2;
4118
4119         return 0;
4120 }
4121
4122
4123 /* JNI_GetCreatedJavaVMs *******************************************************
4124
4125    Returns all Java VMs that have been created. Pointers to VMs are written in
4126    the buffer vmBuf in the order they are created. At most bufLen number of
4127    entries will be written. The total number of created VMs is returned in
4128    *nVMs.
4129
4130 *******************************************************************************/
4131
4132 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4133 {
4134         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4135
4136         return 0;
4137 }
4138
4139
4140 /* JNI_CreateJavaVM ************************************************************
4141
4142    Loads and initializes a Java VM. The current thread becomes the main thread.
4143    Sets the env argument to the JNI interface pointer of the main thread.
4144
4145 *******************************************************************************/
4146
4147 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4148 {
4149         *p_vm = (JavaVM *) &JNI_JavaVMTable;
4150         *p_env = (JNIEnv *) &JNI_JNIEnvTable;
4151
4152         return 0;
4153 }
4154
4155
4156 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4157                                                                            jobject obj, java_objectarray *params)
4158 {
4159         jni_callblock *blk;
4160         jobject        o;
4161         s4             argcount;
4162
4163         if (methodID == 0) {
4164                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
4165                 return NULL;
4166         }
4167
4168         argcount = methodID->parseddesc->paramcount;
4169
4170         /* if method is non-static, remove the `this' pointer */
4171
4172         if (!(methodID->flags & ACC_STATIC))
4173                 argcount--;
4174
4175         /* the method is an instance method the obj has to be an instance of the 
4176            class the method belongs to. For static methods the obj parameter
4177            is ignored. */
4178
4179         if (!(methodID->flags & ACC_STATIC) && obj &&
4180                 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4181                 *exceptionptr =
4182                         new_exception_message(string_java_lang_IllegalArgumentException,
4183                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4184                 return NULL;
4185         }
4186
4187
4188 #ifdef arglimit
4189         if (argcount > 3) {
4190                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
4191                 log_text("Too many arguments. invokeNativeHelper does not support that");
4192                 return NULL;
4193         }
4194 #endif
4195
4196         if (((params == NULL) && (argcount != 0)) ||
4197                 (params && (params->header.size != argcount))) {
4198                 *exceptionptr =
4199                         new_exception(string_java_lang_IllegalArgumentException);
4200                 return NULL;
4201         }
4202
4203
4204         if (!(methodID->flags & ACC_STATIC) && !obj)  {
4205                 *exceptionptr =
4206                         new_exception_message(string_java_lang_NullPointerException,
4207                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4208                 return NULL;
4209         }
4210
4211         if ((methodID->flags & ACC_STATIC) && (obj))
4212                 obj = NULL;
4213
4214         if (obj) {
4215                 if ((methodID->flags & ACC_ABSTRACT) ||
4216                         (methodID->class->flags & ACC_INTERFACE)) {
4217                         methodID = get_virtual(obj, methodID);
4218                 }
4219         }
4220
4221         blk = MNEW(jni_callblock, /*4 */argcount + 2);
4222
4223         if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4224                                                                                  params))
4225                 return NULL;
4226
4227         switch (methodID->parseddesc->returntype.decltype) {
4228         case TYPE_VOID:
4229                 (void) asm_calljavafunction2(methodID, argcount + 1,
4230                                                                          (argcount + 1) * sizeof(jni_callblock),
4231                                                                          blk);
4232                 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4233                 break;
4234
4235         case PRIMITIVETYPE_INT: {
4236                 s4 i;
4237                 i = asm_calljavafunction2int(methodID, argcount + 1,
4238                                                                          (argcount + 1) * sizeof(jni_callblock),
4239                                                                          blk);
4240
4241                 o = native_new_and_init_int(class_java_lang_Integer, i);
4242         }
4243         break;
4244
4245         case PRIMITIVETYPE_BYTE: {
4246                 s4 i;
4247                 i = asm_calljavafunction2int(methodID, argcount + 1,
4248                                                                          (argcount + 1) * sizeof(jni_callblock),
4249                                                                          blk);
4250
4251 /*              o = native_new_and_init_int(class_java_lang_Byte, i); */
4252                 o = builtin_new(class_java_lang_Byte);
4253                 CallVoidMethod(env,
4254                                            o,
4255                                            class_resolvemethod(o->vftbl->class,
4256                                                                                    utf_init,
4257                                                                                    utf_byte__void),
4258                                            i);
4259         }
4260         break;
4261
4262         case PRIMITIVETYPE_CHAR: {
4263                 s4 intVal;
4264                 intVal = asm_calljavafunction2int(methodID,
4265                                                                                   argcount + 1,
4266                                                                                   (argcount + 1) * sizeof(jni_callblock),
4267                                                                                   blk);
4268                 o = builtin_new(class_java_lang_Character);
4269                 CallVoidMethod(env,
4270                                            o,
4271                                            class_resolvemethod(o->vftbl->class,
4272                                                                                    utf_init,
4273                                                                                    utf_char__void),
4274                                            intVal);
4275         }
4276         break;
4277
4278         case PRIMITIVETYPE_SHORT: {
4279                 s4 intVal;
4280                 intVal = asm_calljavafunction2int(methodID,
4281                                                                                   argcount + 1,
4282                                                                                   (argcount + 1) * sizeof(jni_callblock),
4283                                                                                   blk);
4284                 o = builtin_new(class_java_lang_Short);
4285                 CallVoidMethod(env,
4286                                            o,
4287                                            class_resolvemethod(o->vftbl->class,
4288                                                                                    utf_init,
4289                                                                                    utf_short__void),
4290                                            intVal);
4291         }
4292         break;
4293
4294         case PRIMITIVETYPE_BOOLEAN: {
4295                 s4 intVal;
4296                 intVal = asm_calljavafunction2int(methodID,
4297                                                                                   argcount + 1,
4298                                                                                   (argcount + 1) * sizeof(jni_callblock),
4299                                                                                   blk);
4300                 o = builtin_new(class_java_lang_Boolean);
4301                 CallVoidMethod(env,
4302                                            o,
4303                                            class_resolvemethod(o->vftbl->class,
4304                                                                                    utf_init,
4305                                                                                    utf_boolean__void),
4306                                            intVal);
4307         }
4308         break;
4309
4310         case 'J': {
4311                 jlong longVal;
4312                 longVal = asm_calljavafunction2long(methodID,
4313                                                                                         argcount + 1,
4314                                                                                         (argcount + 1) * sizeof(jni_callblock),
4315                                                                                         blk);
4316                 o = builtin_new(class_java_lang_Long);
4317                 CallVoidMethod(env,
4318                                            o,
4319                                            class_resolvemethod(o->vftbl->class,
4320                                                                                    utf_init,
4321                                                                                    utf_long__void),
4322                                            longVal);
4323         }
4324         break;
4325
4326         case PRIMITIVETYPE_FLOAT: {
4327                 jdouble floatVal;       
4328                 floatVal = asm_calljavafunction2float(methodID,
4329                                                                                           argcount + 1,
4330                                                                                           (argcount + 1) * sizeof(jni_callblock),
4331                                                                                           blk);
4332                 o = builtin_new(class_java_lang_Float);
4333                 CallVoidMethod(env,
4334                                            o,
4335                                            class_resolvemethod(o->vftbl->class,
4336                                                                                    utf_init,
4337                                                                                    utf_float__void),
4338                                            floatVal);
4339         }
4340         break;
4341
4342         case PRIMITIVETYPE_DOUBLE: {
4343                 jdouble doubleVal;
4344                 doubleVal = asm_calljavafunction2double(methodID,
4345                                                                                                 argcount + 1,
4346                                                                                                 (argcount + 1) * sizeof(jni_callblock),
4347                                                                                                 blk);
4348                 o = builtin_new(class_java_lang_Double);
4349                 CallVoidMethod(env,
4350                                            o,
4351                                            class_resolvemethod(o->vftbl->class,
4352                                                                                    utf_init,
4353                                                                                    utf_double__void),
4354                                            doubleVal);
4355         }
4356         break;
4357
4358         case TYPE_ADR:
4359                 o = asm_calljavafunction2(methodID, argcount + 1,
4360                                                                   (argcount + 1) * sizeof(jni_callblock), blk);
4361                 break;
4362
4363         default:
4364                 /* if this happens the exception has already been set by              */
4365                 /* fill_callblock_from_objectarray                                    */
4366
4367                 MFREE(blk, jni_callblock, /*4 */ argcount+2);
4368                 return (jobject *) 0;
4369         }
4370
4371         MFREE(blk, jni_callblock, /* 4 */ argcount+2);
4372
4373         if (*exceptionptr) {
4374                 java_objectheader *cause;
4375
4376                 cause = *exceptionptr;
4377
4378                 /* clear exception pointer, we are calling JIT code again */
4379
4380                 *exceptionptr = NULL;
4381
4382                 *exceptionptr =
4383                         new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4384                                                                         (java_lang_Throwable *) cause);
4385         }
4386
4387         return (jobject *) o;
4388 }
4389
4390
4391 /*
4392  * These are local overrides for various environment variables in Emacs.
4393  * Please do not remove this and leave it at the end of the file, where
4394  * Emacs will automagically detect them.
4395  * ---------------------------------------------------------------------
4396  * Local variables:
4397  * mode: c
4398  * indent-tabs-mode: t
4399  * c-basic-offset: 4
4400  * tab-width: 4
4401  * End:
4402  */