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