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