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