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