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