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