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