- asm_calljavafunction2 warning fixes
[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 1853 2005-01-04 12:07:41Z 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 /********************* returns version of native method interface *****************/
782
783 jint GetVersion (JNIEnv* env)
784 {
785         return JNI_VERSION;
786 }
787
788
789 /************** loads a class from a buffer of raw class data *****************/
790
791 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len) 
792 {
793         jclass c; 
794         jclass r;
795         classbuffer *cb;
796
797         c = class_new(utf_new_char_classname((char *) name));
798
799 #if defined(USE_THREADS)
800         /* enter a monitor on the class */
801
802         builtin_monitorenter((java_objectheader *) c);
803 #endif
804
805         /* measure time */
806         if (getloadingtime)
807                 loadingtime_start();
808
809         /* build a classbuffer with the given data */
810         cb = NEW(classbuffer);
811         cb->class = c;
812         cb->size = len;
813         cb->data = (u1 *) buf;
814         cb->pos = cb->data - 1;
815
816         r = class_load_intern(cb);
817
818         /* if return value is NULL, we had a problem and the class is not loaded */
819         if (!r) {
820                 c->loaded = false;
821
822                 /* now free the allocated memory, otherwise we could ran into a DOS */
823                 class_remove(c);
824         }
825
826         /* free memory */
827         FREE(cb, classbuffer);
828
829         /* measure time */
830         if (getloadingtime)
831                 loadingtime_stop();
832
833 #if defined(USE_THREADS)
834         /* leave the monitor */
835
836         builtin_monitorexit((java_objectheader *) c);
837 #endif
838
839         /* XXX link the class here? */
840 /*      if (class_link(c)) */
841 /*              return NULL; */
842
843         if (r) {
844                 c->classloader = loader;
845                 use_class_as_object(r);
846         }
847
848         return r;
849 }
850
851
852 /*********** loads locally defined class with the specified name **************/
853
854 jclass FindClass(JNIEnv* env, const char *name) 
855 {
856         classinfo *c;  
857   
858         c = class_new(utf_new_char_classname((char *) name));
859
860         if (!class_load(c))
861                 return NULL;
862
863         if (!class_link(c))
864                 return NULL;
865
866         use_class_as_object(c);
867
868         return c;
869 }
870   
871
872 /*******************************************************************************
873
874         converts java.lang.reflect.Method or 
875         java.lang.reflect.Constructor object to a method ID  
876   
877 *******************************************************************************/
878   
879 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
880 {
881         /* log_text("JNI-Call: FromReflectedMethod"); */
882
883         return 0;
884 }
885
886
887 /*************** return superclass of the class represented by sub ****************/
888  
889 jclass GetSuperclass(JNIEnv* env, jclass sub) 
890 {
891         classinfo *c;
892
893         c = ((classinfo*) sub)->super;
894
895         if (!c) return NULL; 
896
897         use_class_as_object(c);
898
899         return c;               
900 }
901   
902  
903 /* IsAssignableFrom ************************************************************
904
905    Determines whether an object of sub can be safely cast to sup.
906
907 *******************************************************************************/
908
909 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
910 {
911         return builtin_isanysubclass(sub, sup);
912 }
913
914
915 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
916
917 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
918 {
919         /* log_text("JNI-Call: ToReflectedField"); */
920
921         return NULL;
922 }
923
924
925 /***************** throw java.lang.Throwable object  ******************************/
926
927 jint Throw(JNIEnv* env, jthrowable obj)
928 {
929         *exceptionptr = (java_objectheader*) obj;
930
931         return 0;
932 }
933
934
935 /*******************************************************************************
936
937         create exception object from the class clazz with the 
938         specified message and cause it to be thrown
939
940 *******************************************************************************/
941
942 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
943 {
944         java_lang_Throwable *o;
945
946         /* instantiate exception object */
947         o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
948
949         if (!o) return (-1);
950
951         o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
952
953         *exceptionptr = (java_objectheader *) o;
954
955         return 0;
956 }
957
958
959 /************************* check if exception occured *****************************/
960
961 jthrowable ExceptionOccurred (JNIEnv* env) 
962 {
963         return (jthrowable) *exceptionptr;
964 }
965
966 /********** print exception and a backtrace of the stack (for debugging) **********/
967
968 void ExceptionDescribe (JNIEnv* env) 
969 {
970         utf_display((*exceptionptr)->vftbl->class->name);
971         printf ("\n");
972         fflush (stdout);        
973 }
974
975
976 /******************* clear any exception currently being thrown *******************/
977
978 void ExceptionClear (JNIEnv* env) 
979 {
980         *exceptionptr = NULL;   
981 }
982
983
984 /********** raises a fatal error and does not expect the VM to recover ************/
985
986 void FatalError (JNIEnv* env, const char *msg)
987 {
988         panic((char *) msg);    
989 }
990
991 /******************* creates a new local reference frame **************************/ 
992
993 jint PushLocalFrame(JNIEnv* env, jint capacity)
994 {
995         /* empty */
996
997         return 0;
998 }
999
1000 /**************** Pops off the current local reference frame **********************/
1001
1002 jobject PopLocalFrame(JNIEnv* env, jobject result)
1003 {
1004     log_text("JNI-Call: PopLocalFrame");
1005         /* empty */
1006
1007         return NULL;
1008 }
1009
1010
1011 /*************** Deletes the local reference pointed to by localRef ***************/
1012
1013 void DeleteLocalRef (JNIEnv* env, jobject localRef)
1014 {
1015 /*    log_text("JNI-Call: DeleteLocalRef");*/
1016         /* empty */
1017 }
1018
1019 /********** Tests whether two references refer to the same Java object ************/
1020
1021 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1022 {
1023         return (obj1==obj2);
1024 }
1025
1026 /***** Creates a new local reference that refers to the same object as ref  *******/
1027
1028 jobject NewLocalRef (JNIEnv* env, jobject ref)
1029 {
1030         return ref;
1031 }
1032
1033 /*********************************************************************************** 
1034
1035         Ensures that at least a given number of local references can 
1036         be created in the current thread
1037
1038  **********************************************************************************/   
1039
1040 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1041 {
1042         return 0; /* return 0 on success */
1043 }
1044
1045
1046 /********* Allocates a new Java object without invoking a constructor *************/
1047
1048 jobject AllocObject (JNIEnv* env, jclass clazz)
1049 {
1050         java_objectheader *o = builtin_new(clazz);      
1051         return o;
1052 }
1053
1054
1055 /*********************************************************************************** 
1056
1057         Constructs a new Java object
1058         arguments that are to be passed to the constructor are placed after methodID
1059
1060 ***********************************************************************************/
1061
1062 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1063 {
1064         java_objectheader *o;
1065         void* args[3];
1066         int argcount=get_parametercount(methodID);
1067         int i;
1068         va_list vaargs;
1069
1070         /* log_text("JNI-Call: NewObject"); */
1071
1072 #ifdef arglimit
1073         if (argcount > 3) {
1074                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1075                 log_text("Too many arguments. NewObject does not support that");
1076                 return 0;
1077         }
1078 #endif
1079         
1080         o = builtin_new (clazz);         /*          create object */
1081         
1082         if (!o) return NULL;
1083
1084         va_start(vaargs,methodID);
1085         for (i=0;i<argcount;i++) {
1086                 args[i]=va_arg(vaargs,void*);
1087         }
1088         va_end(vaargs);
1089         asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1090
1091         return o;
1092 }
1093
1094
1095 /*********************************************************************************** 
1096
1097        Constructs a new Java object
1098        arguments that are to be passed to the constructor are placed in va_list args 
1099
1100 ***********************************************************************************/
1101
1102 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1103 {
1104         /* log_text("JNI-Call: NewObjectV"); */
1105
1106         return NULL;
1107 }
1108
1109
1110 /*********************************************************************************** 
1111
1112         Constructs a new Java object
1113         arguments that are to be passed to the constructor are placed in 
1114         args array of jvalues 
1115
1116 ***********************************************************************************/
1117
1118 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1119 {
1120         /* log_text("JNI-Call: NewObjectA"); */
1121
1122         return NULL;
1123 }
1124
1125
1126 /************************ returns the class of an object **************************/ 
1127
1128 jclass GetObjectClass(JNIEnv* env, jobject obj)
1129 {
1130         classinfo *c = obj->vftbl->class;
1131
1132         use_class_as_object(c);
1133
1134         return c;
1135 }
1136
1137
1138 /************* tests whether an object is an instance of a class ******************/
1139
1140 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1141 {
1142         return builtin_instanceof(obj,clazz);
1143 }
1144
1145
1146 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1147  
1148 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1149 {
1150         log_text("JNI-Call: FromReflectedField");
1151
1152         return 0;
1153 }
1154
1155
1156 /**********************************************************************************
1157
1158         converts a method ID to a java.lang.reflect.Method or 
1159         java.lang.reflect.Constructor object
1160
1161 **********************************************************************************/
1162
1163 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1164 {
1165         log_text("JNI-Call: ToReflectedMethod");
1166
1167         return NULL;
1168 }
1169
1170
1171 /* GetMethodID *****************************************************************
1172
1173    returns the method ID for an instance method
1174
1175 *******************************************************************************/
1176
1177 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1178 {
1179         jmethodID m;
1180
1181         m = class_resolvemethod(clazz, 
1182                                                         utf_new_char((char *) name), 
1183                                                         utf_new_char((char *) sig));
1184
1185         if (!m || (m->flags & ACC_STATIC)) {
1186                 *exceptionptr =
1187                         new_exception_message(string_java_lang_NoSuchMethodError, name);
1188
1189                 return 0;
1190         }
1191
1192         return m;
1193 }
1194
1195
1196 /******************** JNI-functions for calling instance methods ******************/
1197
1198 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1199 {
1200         jobject ret;
1201         va_list vaargs;
1202
1203 /*      log_text("JNI-Call: CallObjectMethod");*/
1204
1205         va_start(vaargs, methodID);
1206         ret = callObjectMethod(obj, methodID, vaargs);
1207         va_end(vaargs);
1208
1209         return ret;
1210 }
1211
1212
1213 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1214 {
1215         return callObjectMethod(obj,methodID,args);
1216 }
1217
1218
1219 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1220 {
1221         log_text("JNI-Call: CallObjectMethodA");
1222
1223         return NULL;
1224 }
1225
1226
1227
1228
1229 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1230 {
1231         jboolean ret;
1232         va_list vaargs;
1233
1234 /*      log_text("JNI-Call: CallBooleanMethod");*/
1235
1236         va_start(vaargs,methodID);
1237         ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1238         va_end(vaargs);
1239         return ret;
1240
1241 }
1242
1243 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1244 {
1245         return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1246
1247 }
1248
1249 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1250 {
1251         log_text("JNI-Call: CallBooleanMethodA");
1252
1253         return 0;
1254 }
1255
1256 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1257 {
1258         jbyte ret;
1259         va_list vaargs;
1260
1261 /*      log_text("JNI-Call: CallVyteMethod");*/
1262
1263         va_start(vaargs,methodID);
1264         ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1265         va_end(vaargs);
1266         return ret;
1267
1268 }
1269
1270 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1271 {
1272 /*      log_text("JNI-Call: CallByteMethodV");*/
1273         return callIntegerMethod(obj,methodID,'B',args);
1274 }
1275
1276
1277 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1278 {
1279         log_text("JNI-Call: CallByteMethodA");
1280
1281         return 0;
1282 }
1283
1284
1285 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1286 {
1287         jchar ret;
1288         va_list vaargs;
1289
1290 /*      log_text("JNI-Call: CallCharMethod");*/
1291
1292         va_start(vaargs,methodID);
1293         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1294         va_end(vaargs);
1295
1296         return ret;
1297 }
1298
1299
1300 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1301 {
1302 /*      log_text("JNI-Call: CallCharMethodV");*/
1303         return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1304 }
1305
1306
1307 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1308 {
1309         log_text("JNI-Call: CallCharMethodA");
1310
1311         return 0;
1312 }
1313
1314
1315 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1316 {
1317         jshort ret;
1318         va_list vaargs;
1319
1320 /*      log_text("JNI-Call: CallShortMethod");*/
1321
1322         va_start(vaargs, methodID);
1323         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1324         va_end(vaargs);
1325
1326         return ret;
1327 }
1328
1329
1330 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1331 {
1332         return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1333 }
1334
1335
1336 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1337 {
1338         log_text("JNI-Call: CallShortMethodA");
1339
1340         return 0;
1341 }
1342
1343
1344
1345 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1346 {
1347         jint ret;
1348         va_list vaargs;
1349
1350         va_start(vaargs,methodID);
1351         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1352         va_end(vaargs);
1353
1354         return ret;
1355 }
1356
1357
1358 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1359 {
1360         return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1361 }
1362
1363
1364 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1365 {
1366         log_text("JNI-Call: CallIntMethodA");
1367
1368         return 0;
1369 }
1370
1371
1372
1373 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1374 {
1375         jlong ret;
1376         va_list vaargs;
1377         
1378         va_start(vaargs,methodID);
1379         ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1380         va_end(vaargs);
1381
1382         return ret;
1383 }
1384
1385
1386 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1387 {
1388         return  callLongMethod(obj,get_virtual(obj, methodID),args);
1389 }
1390
1391
1392 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1393 {
1394         log_text("JNI-Call: CallLongMethodA");
1395
1396         return 0;
1397 }
1398
1399
1400
1401 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1402 {
1403         jfloat ret;
1404         va_list vaargs;
1405
1406 /*      log_text("JNI-Call: CallFloatMethod");*/
1407
1408         va_start(vaargs,methodID);
1409         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1410         va_end(vaargs);
1411
1412         return ret;
1413 }
1414
1415
1416 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1417 {
1418         log_text("JNI-Call: CallFloatMethodV");
1419         return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1420 }
1421
1422
1423 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1424 {
1425         log_text("JNI-Call: CallFloatMethodA");
1426
1427         return 0;
1428 }
1429
1430
1431
1432 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1433 {
1434         jdouble ret;
1435         va_list vaargs;
1436
1437 /*      log_text("JNI-Call: CallDoubleMethod");*/
1438
1439         va_start(vaargs,methodID);
1440         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1441         va_end(vaargs);
1442
1443         return ret;
1444 }
1445
1446
1447 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1448 {
1449         log_text("JNI-Call: CallDoubleMethodV");
1450         return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1451 }
1452
1453
1454 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1455 {
1456         log_text("JNI-Call: CallDoubleMethodA");
1457         return 0;
1458 }
1459
1460
1461
1462 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1463 {
1464         va_list vaargs;
1465
1466         va_start(vaargs,methodID);
1467         (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1468         va_end(vaargs);
1469 }
1470
1471
1472 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1473 {
1474         log_text("JNI-Call: CallVoidMethodV");
1475         (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1476 }
1477
1478
1479 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1480 {
1481         log_text("JNI-Call: CallVoidMethodA");
1482 }
1483
1484
1485
1486 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1487 {
1488         log_text("JNI-Call: CallNonvirtualObjectMethod");
1489
1490         return NULL;
1491 }
1492
1493
1494 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1495 {
1496         log_text("JNI-Call: CallNonvirtualObjectMethodV");
1497
1498         return NULL;
1499 }
1500
1501
1502 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1503 {
1504         log_text("JNI-Call: CallNonvirtualObjectMethodA");
1505
1506         return NULL;
1507 }
1508
1509
1510
1511 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1512 {
1513         jboolean ret;
1514         va_list vaargs;
1515
1516 /*      log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1517
1518         va_start(vaargs,methodID);
1519         ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1520         va_end(vaargs);
1521         return ret;
1522
1523 }
1524
1525
1526 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1527 {
1528 /*      log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1529         return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1530 }
1531
1532
1533 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1534 {
1535         log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1536
1537         return 0;
1538 }
1539
1540
1541
1542 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1543 {
1544         jbyte ret;
1545         va_list vaargs;
1546
1547 /*      log_text("JNI-Call: CallNonvirutalByteMethod");*/
1548
1549         va_start(vaargs,methodID);
1550         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1551         va_end(vaargs);
1552         return ret;
1553 }
1554
1555
1556 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1557 {
1558         /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1559         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1560
1561 }
1562
1563
1564 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1565 {
1566         log_text("JNI-Call: CallNonvirtualByteMethodA");
1567
1568         return 0;
1569 }
1570
1571
1572
1573 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1574 {
1575         jchar ret;
1576         va_list vaargs;
1577
1578 /*      log_text("JNI-Call: CallNonVirtualCharMethod");*/
1579
1580         va_start(vaargs,methodID);
1581         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1582         va_end(vaargs);
1583         return ret;
1584 }
1585
1586
1587 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1588 {
1589         /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1590         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1591 }
1592
1593
1594 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1595 {
1596         log_text("JNI-Call: CallNonvirtualCharMethodA");
1597
1598         return 0;
1599 }
1600
1601
1602
1603 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1604 {
1605         jshort ret;
1606         va_list vaargs;
1607
1608         /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1609
1610         va_start(vaargs,methodID);
1611         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1612         va_end(vaargs);
1613         return ret;
1614 }
1615
1616
1617 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1618 {
1619         /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1620         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1621 }
1622
1623
1624 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1625 {
1626         log_text("JNI-Call: CallNonvirtualShortMethodA");
1627
1628         return 0;
1629 }
1630
1631
1632
1633 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1634 {
1635
1636         jint ret;
1637         va_list vaargs;
1638
1639         /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1640
1641         va_start(vaargs,methodID);
1642         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1643         va_end(vaargs);
1644         return ret;
1645 }
1646
1647
1648 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1649 {
1650         /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1651         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1652 }
1653
1654
1655 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1656 {
1657         log_text("JNI-Call: CallNonvirtualIntMethodA");
1658
1659         return 0;
1660 }
1661
1662
1663
1664 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1665 {
1666         log_text("JNI-Call: CallNonvirtualLongMethod");
1667
1668         return 0;
1669 }
1670
1671
1672 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1673 {
1674         log_text("JNI-Call: CallNonvirtualLongMethodV");
1675
1676         return 0;
1677 }
1678
1679
1680 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1681 {
1682         log_text("JNI-Call: CallNonvirtualLongMethodA");
1683
1684         return 0;
1685 }
1686
1687
1688
1689 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1690 {
1691         jfloat ret;
1692         va_list vaargs;
1693
1694         /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1695
1696
1697         va_start(vaargs,methodID);
1698         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1699         va_end(vaargs);
1700         return ret;
1701
1702 }
1703
1704
1705 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1706 {
1707         log_text("JNI-Call: CallNonvirtualFloatMethodV");
1708         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1709 }
1710
1711
1712 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1713 {
1714         log_text("JNI-Call: CallNonvirtualFloatMethodA");
1715
1716         return 0;
1717 }
1718
1719
1720
1721 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1722 {
1723         jdouble ret;
1724         va_list vaargs;
1725         log_text("JNI-Call: CallNonvirtualDoubleMethod");
1726
1727         va_start(vaargs,methodID);
1728         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1729         va_end(vaargs);
1730         return ret;
1731
1732 }
1733
1734
1735 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1736 {
1737 /*      log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1738         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1739 }
1740
1741
1742 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1743 {
1744         log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1745
1746         return 0;
1747 }
1748
1749
1750
1751 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1752 {
1753         va_list vaargs;
1754
1755 /*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1756
1757         va_start(vaargs,methodID);
1758         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1759         va_end(vaargs);
1760
1761 }
1762
1763
1764 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1765 {
1766 /*      log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1767
1768         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1769
1770 }
1771
1772
1773 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1774 {
1775         log_text("JNI-Call: CallNonvirtualVoidMethodA");
1776 }
1777
1778 /************************* JNI-functions for accessing fields ************************/
1779
1780 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
1781 {
1782         jfieldID f;
1783
1784 /*      log_text("========================= searching for:");
1785         log_text(name);
1786         log_text(sig);*/
1787         f = jclass_findfield(clazz,
1788                             utf_new_char ((char*) name), 
1789                             utf_new_char ((char*) sig)
1790                             ); 
1791         
1792         if (!f) { 
1793                 /*utf_display(clazz->name);
1794                 log_text(name);
1795                 log_text(sig);*/
1796                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
1797         }
1798         return f;
1799 }
1800
1801 /*************************** retrieve fieldid, abort on error ************************/
1802
1803 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1804 {
1805     jfieldID id = GetFieldID(env, clazz, name, sig);
1806
1807     if (!id) {
1808        log_text("class:");
1809        utf_display(clazz->name);
1810        log_text("\nfield:");
1811        log_text(name);
1812        log_text("sig:");
1813        log_text(sig);
1814
1815        panic("setfield_critical failed"); 
1816     }
1817     return id;
1818 }
1819
1820 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1821 {
1822         /*
1823         jobject dbg,dretval,*dpretval;  
1824         long int dli1, dli2, dli3;
1825
1826         printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
1827                          ((threadobject *) THREADOBJECT)->o
1828                          .thread->name,NULL)
1829                          ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);
1830
1831         dbg = getField(obj,jobject,fieldID);
1832         dli1 = (long int) obj;
1833         dli2 = (long int) fieldID->offset;
1834         dli3 = dli1+dli2;
1835         dpretval = (jobject*) dli3;
1836         dretval = *dpretval;
1837         jclass tmp;
1838         jmethodID mid;
1839         jstring jstr;
1840
1841         tmp = FindClass(env, "java/lang/Object");
1842         mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
1843         jstr = CallObjectMethod(env,dbg,mid);*/
1844
1845 /*      printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
1846         ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
1847
1848
1849 /*      return dbg;*/
1850
1851         return getField(obj,jobject,fieldID);
1852 }
1853
1854 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1855 {
1856         return getField(obj,jboolean,fieldID);
1857 }
1858
1859
1860 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1861 {
1862         return getField(obj,jbyte,fieldID);
1863 }
1864
1865
1866 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1867 {
1868         return getField(obj,jchar,fieldID);
1869 }
1870
1871
1872 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1873 {
1874         return getField(obj,jshort,fieldID);
1875 }
1876
1877
1878 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1879 {
1880         return getField(obj,jint,fieldID);
1881 }
1882
1883
1884 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1885 {
1886         return getField(obj,jlong,fieldID);
1887 }
1888
1889
1890 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1891 {
1892         return getField(obj,jfloat,fieldID);
1893 }
1894
1895
1896 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1897 {
1898         return getField(obj,jdouble,fieldID);
1899 }
1900
1901 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1902 {
1903         setField(obj,jobject,fieldID,val);
1904 }
1905
1906
1907 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1908 {
1909         setField(obj,jboolean,fieldID,val);
1910 }
1911
1912
1913 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1914 {
1915         setField(obj,jbyte,fieldID,val);
1916 }
1917
1918
1919 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1920 {
1921         setField(obj,jchar,fieldID,val);
1922 }
1923
1924
1925 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1926 {
1927         setField(obj,jshort,fieldID,val);
1928 }
1929
1930
1931 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1932 {
1933         setField(obj,jint,fieldID,val);
1934 }
1935
1936
1937 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1938 {
1939         setField(obj,jlong,fieldID,val);
1940 }
1941
1942
1943 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1944 {
1945         setField(obj,jfloat,fieldID,val);
1946 }
1947
1948
1949 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1950 {
1951         setField(obj,jdouble,fieldID,val);
1952 }
1953
1954
1955 /**************** JNI-functions for calling static methods **********************/ 
1956
1957 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1958 {
1959         jmethodID m;
1960
1961         m = class_resolvemethod(clazz,
1962                                                         utf_new_char((char *) name),
1963                                                         utf_new_char((char *) sig));
1964
1965         if (!m || !(m->flags & ACC_STATIC)) {
1966                 *exceptionptr =
1967                         new_exception_message(string_java_lang_NoSuchMethodError, name);
1968
1969                 return NULL;
1970         }
1971
1972         return m;
1973 }
1974
1975
1976 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1977 {
1978         jobject ret;
1979         va_list vaargs;
1980
1981         /* log_text("JNI-Call: CallStaticObjectMethod");*/
1982
1983         va_start(vaargs, methodID);
1984         ret = callObjectMethod(0, methodID, vaargs);
1985         va_end(vaargs);
1986
1987         return ret;
1988 }
1989
1990
1991 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1992 {
1993         /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1994         
1995         return callObjectMethod(0,methodID,args);
1996 }
1997
1998
1999 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2000 {
2001         log_text("JNI-Call: CallStaticObjectMethodA");
2002
2003         return NULL;
2004 }
2005
2006
2007 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2008 {
2009         jboolean ret;
2010         va_list vaargs;
2011
2012         va_start(vaargs, methodID);
2013         ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
2014         va_end(vaargs);
2015
2016         return ret;
2017 }
2018
2019
2020 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2021 {
2022         return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
2023 }
2024
2025
2026 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2027 {
2028         log_text("JNI-Call: CallStaticBooleanMethodA");
2029
2030         return 0;
2031 }
2032
2033
2034 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2035 {
2036         jbyte ret;
2037         va_list vaargs;
2038
2039         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2040
2041         va_start(vaargs, methodID);
2042         ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
2043         va_end(vaargs);
2044
2045         return ret;
2046 }
2047
2048
2049 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2050 {
2051         return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2052 }
2053
2054
2055 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2056 {
2057         log_text("JNI-Call: CallStaticByteMethodA");
2058
2059         return 0;
2060 }
2061
2062
2063 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2064 {
2065         jchar ret;
2066         va_list vaargs;
2067
2068         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2069
2070         va_start(vaargs, methodID);
2071         ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2072         va_end(vaargs);
2073
2074         return ret;
2075 }
2076
2077
2078 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2079 {
2080         return (jchar) callIntegerMethod(0, methodID, 'C', args);
2081 }
2082
2083
2084 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2085 {
2086         log_text("JNI-Call: CallStaticCharMethodA");
2087
2088         return 0;
2089 }
2090
2091
2092
2093 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2094 {
2095         jshort ret;
2096         va_list vaargs;
2097
2098         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2099
2100         va_start(vaargs, methodID);
2101         ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2102         va_end(vaargs);
2103
2104         return ret;
2105 }
2106
2107
2108 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2109 {
2110         /*log_text("JNI-Call: CallStaticShortMethodV");*/
2111         return (jshort) callIntegerMethod(0, methodID, 'S', args);
2112 }
2113
2114
2115 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2116 {
2117         log_text("JNI-Call: CallStaticShortMethodA");
2118
2119         return 0;
2120 }
2121
2122
2123
2124 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2125 {
2126         jint ret;
2127         va_list vaargs;
2128
2129         /*      log_text("JNI-Call: CallStaticIntMethod");*/
2130
2131         va_start(vaargs, methodID);
2132         ret = callIntegerMethod(0, methodID, 'I', vaargs);
2133         va_end(vaargs);
2134
2135         return ret;
2136 }
2137
2138
2139 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2140 {
2141         log_text("JNI-Call: CallStaticIntMethodV");
2142
2143         return callIntegerMethod(0, methodID, 'I', args);
2144 }
2145
2146
2147 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2148 {
2149         log_text("JNI-Call: CallStaticIntMethodA");
2150
2151         return 0;
2152 }
2153
2154
2155
2156 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2157 {
2158         jlong ret;
2159         va_list vaargs;
2160
2161         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2162
2163         va_start(vaargs, methodID);
2164         ret = callLongMethod(0, methodID, vaargs);
2165         va_end(vaargs);
2166
2167         return ret;
2168 }
2169
2170
2171 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2172 {
2173         log_text("JNI-Call: CallStaticLongMethodV");
2174         
2175         return callLongMethod(0,methodID,args);
2176 }
2177
2178
2179 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2180 {
2181         log_text("JNI-Call: CallStaticLongMethodA");
2182
2183         return 0;
2184 }
2185
2186
2187
2188 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2189 {
2190         jfloat ret;
2191         va_list vaargs;
2192
2193         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2194
2195         va_start(vaargs, methodID);
2196         ret = callFloatMethod(0, methodID, vaargs, 'F');
2197         va_end(vaargs);
2198
2199         return ret;
2200 }
2201
2202
2203 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2204 {
2205
2206         return callFloatMethod(0, methodID, args, 'F');
2207
2208 }
2209
2210
2211 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2212 {
2213         log_text("JNI-Call: CallStaticFloatMethodA");
2214
2215         return 0;
2216 }
2217
2218
2219
2220 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2221 {
2222         jdouble ret;
2223         va_list vaargs;
2224
2225         /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
2226
2227         va_start(vaargs,methodID);
2228         ret = callFloatMethod(0, methodID, vaargs, 'D');
2229         va_end(vaargs);
2230
2231         return ret;
2232 }
2233
2234
2235 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2236 {
2237         log_text("JNI-Call: CallStaticDoubleMethodV");
2238
2239         return callFloatMethod(0, methodID, args, 'D');
2240 }
2241
2242
2243 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2244 {
2245         log_text("JNI-Call: CallStaticDoubleMethodA");
2246
2247         return 0;
2248 }
2249
2250
2251 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2252 {
2253         va_list vaargs;
2254
2255         va_start(vaargs, methodID);
2256         (void) callIntegerMethod(0, methodID, 'V', vaargs);
2257         va_end(vaargs);
2258 }
2259
2260
2261 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2262 {
2263         log_text("JNI-Call: CallStaticVoidMethodV");
2264         (void)callIntegerMethod(0, methodID, 'V', args);
2265 }
2266
2267
2268 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2269 {
2270         log_text("JNI-Call: CallStaticVoidMethodA");
2271 }
2272
2273
2274 /****************** JNI-functions for accessing static fields ********************/
2275
2276 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
2277 {
2278         jfieldID f;
2279
2280         f = jclass_findfield(clazz,
2281                             utf_new_char ((char*) name), 
2282                             utf_new_char ((char*) sig)
2283                             ); 
2284         
2285         if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2286
2287         return f;
2288 }
2289
2290
2291 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2292 {
2293         class_init(clazz);
2294         return fieldID->value.a;       
2295 }
2296
2297
2298 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2299 {
2300         class_init(clazz);
2301         return fieldID->value.i;       
2302 }
2303
2304
2305 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2306 {
2307         class_init(clazz);
2308         return fieldID->value.i;       
2309 }
2310
2311
2312 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2313 {
2314         class_init(clazz);
2315         return fieldID->value.i;       
2316 }
2317
2318
2319 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2320 {
2321         class_init(clazz);
2322         return fieldID->value.i;       
2323 }
2324
2325
2326 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2327 {
2328         class_init(clazz);
2329         return fieldID->value.i;       
2330 }
2331
2332
2333 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2334 {
2335         class_init(clazz);
2336         return fieldID->value.l;
2337 }
2338
2339
2340 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2341 {
2342         class_init(clazz);
2343         return fieldID->value.f;
2344 }
2345
2346
2347 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2348 {
2349         class_init(clazz);
2350         return fieldID->value.d;
2351 }
2352
2353
2354
2355 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2356 {
2357         class_init(clazz);
2358         fieldID->value.a = value;
2359 }
2360
2361
2362 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2363 {
2364         class_init(clazz);
2365         fieldID->value.i = value;
2366 }
2367
2368
2369 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2370 {
2371         class_init(clazz);
2372         fieldID->value.i = value;
2373 }
2374
2375
2376 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2377 {
2378         class_init(clazz);
2379         fieldID->value.i = value;
2380 }
2381
2382
2383 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2384 {
2385         class_init(clazz);
2386         fieldID->value.i = value;
2387 }
2388
2389
2390 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2391 {
2392         class_init(clazz);
2393         fieldID->value.i = value;
2394 }
2395
2396
2397 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2398 {
2399         class_init(clazz);
2400         fieldID->value.l = value;
2401 }
2402
2403
2404 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2405 {
2406         class_init(clazz);
2407         fieldID->value.f = value;
2408 }
2409
2410
2411 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2412 {
2413         class_init(clazz);
2414         fieldID->value.d = value;
2415 }
2416
2417
2418 /*****  create new java.lang.String object from an array of Unicode characters ****/ 
2419
2420 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2421 {
2422         u4 i;
2423         java_lang_String *s;
2424         java_chararray *a;
2425         
2426         s = (java_lang_String*) builtin_new (class_java_lang_String);
2427         a = builtin_newarray_char (len);
2428
2429         /* javastring or characterarray could not be created */
2430         if ( (!a) || (!s) ) return NULL;
2431
2432         /* copy text */
2433         for (i=0; i<len; i++) a->data[i] = buf[i];
2434         s -> value = a;
2435         s -> offset = 0;
2436         s -> count = len;
2437
2438         return (jstring) s;
2439 }
2440
2441
2442 static char emptyString[]="";
2443 static jchar emptyStringJ[]={0,0};
2444
2445 /******************* returns the length of a Java string ***************************/
2446
2447 jsize GetStringLength (JNIEnv *env, jstring str)
2448 {
2449         return ((java_lang_String*) str)->count;
2450 }
2451
2452
2453 /********************  convertes javastring to u2-array ****************************/
2454         
2455 u2 *javastring_tou2 (jstring so) 
2456 {
2457         java_lang_String *s = (java_lang_String*) so;
2458         java_chararray *a;
2459         u4 i;
2460         u2 *stringbuffer;
2461         
2462         if (!s) return NULL;
2463
2464         a = s->value;
2465         if (!a) return NULL;
2466
2467         /* allocate memory */
2468         stringbuffer = MNEW( u2 , s->count + 1 );
2469
2470         /* copy text */
2471         for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2472         
2473         /* terminate string */
2474         stringbuffer[i] = '\0';
2475
2476         return stringbuffer;
2477 }
2478
2479 /********* returns a pointer to an array of Unicode characters of the string *******/
2480
2481 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2482 {       
2483         jchar *jc=javastring_tou2(str);
2484
2485         if (jc) {
2486                 if (isCopy) *isCopy=JNI_TRUE;
2487                 return jc;
2488         }
2489         if (isCopy) *isCopy=JNI_TRUE;
2490         return emptyStringJ;
2491 }
2492
2493 /**************** native code no longer needs access to chars **********************/
2494
2495 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2496 {
2497         if (chars==emptyStringJ) return;
2498         MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2499 }
2500
2501
2502 /* NewStringUTF ****************************************************************
2503
2504    Constructs a new java.lang.String object from an array of UTF-8 characters.
2505
2506 *******************************************************************************/
2507
2508 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2509 {
2510     return (jstring) javastring_new(utf_new_char(bytes));
2511 }
2512
2513
2514 /****************** returns the utf8 length in bytes of a string *******************/
2515
2516 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2517 {   
2518     java_lang_String *s = (java_lang_String*) string;
2519
2520     return (jsize) u2_utflength(s->value->data, s->count); 
2521 }
2522
2523
2524 /************ converts a Javastring to an array of UTF-8 characters ****************/
2525
2526 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2527 {
2528     utf *u;
2529
2530     u = javastring_toutf((java_lang_String *) string, false);
2531
2532     if (isCopy)
2533                 *isCopy = JNI_FALSE;
2534         
2535     if (u)
2536                 return u->text;
2537
2538     return emptyString;
2539         
2540 }
2541
2542
2543 /***************** native code no longer needs access to utf ***********************/
2544
2545 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2546 {
2547     /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2548         the garbage collector will never get them*/
2549         /*
2550     log_text("JNI-Call: ReleaseStringUTFChars");
2551     utf_display(utf_new_char(chars));
2552         */
2553 }
2554
2555 /************************** array operations ***************************************/
2556
2557 jsize GetArrayLength(JNIEnv *env, jarray array)
2558 {
2559     return array->size;
2560 }
2561
2562
2563 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2564 {
2565         java_objectarray *j;
2566
2567     if (len < 0) {
2568                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2569                 return NULL;
2570     }
2571
2572     j = builtin_anewarray(len, clazz);
2573
2574     return j;
2575 }
2576
2577
2578 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2579 {
2580     jobject j = NULL;
2581
2582     if (index < array->header.size)     
2583                 j = array->data[index];
2584     else
2585                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2586     
2587     return j;
2588 }
2589
2590
2591 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2592 {
2593     if (index >= array->header.size)
2594                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2595
2596     else {
2597                 /* check if the class of value is a subclass of the element class of the array */
2598                 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2599                         *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2600
2601                 else
2602                         array->data[index] = val;
2603     }
2604 }
2605
2606
2607
2608 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2609 {
2610         java_booleanarray *j;
2611
2612     if (len < 0) {
2613                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2614                 return NULL;
2615     }
2616
2617     j = builtin_newarray_boolean(len);
2618
2619     return j;
2620 }
2621
2622
2623 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2624 {
2625         java_bytearray *j;
2626
2627     if (len < 0) {
2628                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2629                 return NULL;
2630     }
2631
2632     j = builtin_newarray_byte(len);
2633
2634     return j;
2635 }
2636
2637
2638 jcharArray NewCharArray(JNIEnv *env, jsize len)
2639 {
2640         java_chararray *j;
2641
2642     if (len < 0) {
2643                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2644                 return NULL;
2645     }
2646
2647     j = builtin_newarray_char(len);
2648
2649     return j;
2650 }
2651
2652
2653 jshortArray NewShortArray(JNIEnv *env, jsize len)
2654 {
2655         java_shortarray *j;
2656
2657     if (len < 0) {
2658                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2659                 return NULL;
2660     }
2661
2662     j = builtin_newarray_short(len);
2663
2664     return j;
2665 }
2666
2667
2668 jintArray NewIntArray(JNIEnv *env, jsize len)
2669 {
2670         java_intarray *j;
2671
2672     if (len < 0) {
2673                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2674                 return NULL;
2675     }
2676
2677     j = builtin_newarray_int(len);
2678
2679     return j;
2680 }
2681
2682
2683 jlongArray NewLongArray(JNIEnv *env, jsize len)
2684 {
2685         java_longarray *j;
2686
2687     if (len < 0) {
2688                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2689                 return NULL;
2690     }
2691
2692     j = builtin_newarray_long(len);
2693
2694     return j;
2695 }
2696
2697
2698 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2699 {
2700         java_floatarray *j;
2701
2702     if (len < 0) {
2703                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2704                 return NULL;
2705     }
2706
2707     j = builtin_newarray_float(len);
2708
2709     return j;
2710 }
2711
2712
2713 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2714 {
2715         java_doublearray *j;
2716
2717     if (len < 0) {
2718                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2719                 return NULL;
2720     }
2721
2722     j = builtin_newarray_double(len);
2723
2724     return j;
2725 }
2726
2727
2728 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2729 {
2730     if (isCopy) *isCopy = JNI_FALSE;
2731     return array->data;
2732 }
2733
2734
2735 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2736 {
2737     if (isCopy) *isCopy = JNI_FALSE;
2738     return array->data;
2739 }
2740
2741
2742 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2743 {
2744     if (isCopy) *isCopy = JNI_FALSE;
2745     return array->data;
2746 }
2747
2748
2749 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2750 {
2751     if (isCopy) *isCopy = JNI_FALSE;
2752     return array->data;
2753 }
2754
2755
2756 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2757 {
2758     if (isCopy) *isCopy = JNI_FALSE;
2759     return array->data;
2760 }
2761
2762
2763 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2764 {
2765     if (isCopy) *isCopy = JNI_FALSE;
2766     return array->data;
2767 }
2768
2769
2770 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2771 {
2772     if (isCopy) *isCopy = JNI_FALSE;
2773     return array->data;
2774 }
2775
2776
2777 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2778 {
2779     if (isCopy) *isCopy = JNI_FALSE;
2780     return array->data;
2781 }
2782
2783
2784
2785 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2786 {
2787     /* empty */
2788 }
2789
2790
2791 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2792 {
2793     /* empty */
2794 }
2795
2796
2797 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2798 {
2799     /* empty */
2800 }
2801
2802
2803 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2804 {
2805     /* empty */
2806 }
2807
2808
2809 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2810 {
2811     /* empty */
2812 }
2813
2814
2815 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2816 {
2817     /* empty */
2818 }
2819
2820
2821 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2822 {
2823     /* empty */
2824 }
2825
2826
2827 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2828 {
2829     /* empty */
2830 }
2831
2832
2833 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2834 {
2835     if (start < 0 || len < 0 || start + len > array->header.size)
2836                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2837
2838     else
2839                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2840 }
2841
2842
2843 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2844 {
2845     if (start < 0 || len < 0 || start + len > array->header.size) 
2846                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2847
2848     else
2849                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2850 }
2851
2852
2853 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2854 {
2855     if (start < 0 || len < 0 || start + len > array->header.size)
2856                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2857
2858     else
2859                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2860 }
2861
2862
2863 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2864 {
2865     if (start < 0 || len < 0 || start + len > array->header.size)
2866                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2867
2868     else        
2869                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2870 }
2871
2872
2873 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2874 {
2875     if (start < 0 || len < 0 || start + len > array->header.size)
2876                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2877
2878     else
2879                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2880 }
2881
2882
2883 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2884 {
2885     if (start < 0 || len < 0 || start + len > array->header.size)
2886                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2887
2888     else
2889                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2890 }
2891
2892
2893 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2894 {
2895     if (start < 0 || len < 0 || start + len > array->header.size)
2896                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2897
2898     else
2899                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2900 }
2901
2902
2903 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2904 {
2905     if (start < 0 || len < 0 || start+len>array->header.size)
2906                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2907
2908     else
2909                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2910 }
2911
2912
2913 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2914 {
2915     if (start < 0 || len < 0 || start + len > array->header.size)
2916                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2917
2918     else
2919                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2920 }
2921
2922
2923 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2924 {
2925     if (start < 0 || len < 0 || start + len > array->header.size)
2926                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2927
2928     else
2929                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2930 }
2931
2932
2933 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2934 {
2935     if (start < 0 || len < 0 || start + len > array->header.size)
2936                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2937
2938     else
2939                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2940
2941 }
2942
2943
2944 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2945 {
2946     if (start < 0 || len < 0 || start + len > array->header.size)
2947                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2948
2949     else
2950                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2951 }
2952
2953
2954 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2955 {
2956     if (start < 0 || len < 0 || start + len > array->header.size)
2957                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2958
2959     else
2960                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2961
2962 }
2963
2964
2965 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2966 {
2967     if (start < 0 || len < 0 || start + len > array->header.size)
2968                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2969
2970     else
2971                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2972
2973 }
2974
2975
2976 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2977 {
2978     if (start < 0 || len < 0 || start + len > array->header.size)
2979                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2980
2981     else
2982                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2983
2984 }
2985
2986
2987 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2988 {
2989     if (start < 0 || len < 0 || start + len > array->header.size)
2990                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2991
2992     else
2993                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2994 }
2995
2996
2997 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2998 {
2999     log_text("JNI-Call: RegisterNatives");
3000     return 0;
3001 }
3002
3003
3004 jint UnregisterNatives (JNIEnv* env, jclass clazz)
3005 {
3006     log_text("JNI-Call: UnregisterNatives");
3007     return 0;
3008 }
3009
3010 /******************************* monitor operations ********************************/
3011
3012 jint MonitorEnter(JNIEnv* env, jobject obj)
3013 {
3014 #if defined(USE_THREADS)
3015     builtin_monitorenter(obj);
3016 #endif
3017
3018     return 0;
3019 }
3020
3021
3022 jint MonitorExit(JNIEnv* env, jobject obj)
3023 {
3024 #if defined(USE_THREADS)
3025     builtin_monitorexit(obj);
3026 #endif
3027
3028     return 0;
3029 }
3030
3031
3032 /* JavaVM interface ***********************************************************/
3033
3034 /* GetJavaVM *******************************************************************
3035
3036    Returns the Java VM interface (used in the Invocation API) associated with
3037    the current thread. The result is placed at the location pointed to by the
3038    second argument, vm.
3039
3040 *******************************************************************************/
3041
3042 jint GetJavaVM(JNIEnv* env, JavaVM **vm)
3043 {
3044     *vm = &JNI_javaVMTable;
3045
3046     return 0;
3047 }
3048
3049
3050 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3051 {
3052     log_text("JNI-Call: GetStringRegion");
3053
3054 }
3055
3056 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3057 {
3058     log_text("JNI-Call: GetStringUTFRegion");
3059
3060 }
3061
3062 /************** obtain direct pointer to array elements ***********************/
3063
3064 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3065 {
3066         java_objectheader *s = (java_objectheader*) array;
3067         arraydescriptor *desc = s->vftbl->arraydesc;
3068
3069         if (!desc) return NULL;
3070
3071         return ((u1*)s) + desc->dataoffset;
3072 }
3073
3074
3075 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3076 {
3077         log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3078
3079         /* empty */
3080 }
3081
3082 /**** returns a pointer to an array of Unicode characters of the string *******/
3083
3084 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3085 {
3086         log_text("JNI-Call: GetStringCritical");
3087
3088         return GetStringChars(env,string,isCopy);
3089 }
3090
3091 /*********** native code no longer needs access to chars **********************/
3092
3093 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3094 {
3095         log_text("JNI-Call: ReleaseStringCritical");
3096
3097         ReleaseStringChars(env,string,cstring);
3098 }
3099
3100
3101 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3102 {
3103         log_text("JNI-Call: NewWeakGlobalRef");
3104
3105         return obj;
3106 }
3107
3108
3109 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3110 {
3111         log_text("JNI-Call: DeleteWeakGlobalRef");
3112
3113         /* empty */
3114 }
3115
3116
3117 /** Creates a new global reference to the object referred to by the obj argument **/
3118     
3119 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
3120 {
3121         jobject refcount;
3122         jint val;
3123         jobject newval;
3124
3125         MonitorEnter(env, *global_ref_table);
3126         
3127         refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
3128         val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
3129         newval = NewObject(env, intclass, newint, val + 1);
3130
3131         if (newval != NULL) {
3132                 CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
3133                 MonitorExit(env, *global_ref_table);
3134                 return lobj;
3135
3136         } else {
3137                 log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
3138                 MonitorExit(env, *global_ref_table);
3139                 return NULL;
3140         }
3141 }
3142
3143 /*************  Deletes the global reference pointed to by globalRef **************/
3144
3145 void DeleteGlobalRef(JNIEnv* env, jobject gref)
3146 {
3147         jobject refcount;
3148         jint val;
3149
3150         MonitorEnter(env, *global_ref_table);
3151         refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
3152
3153         if (refcount == NULL) {
3154                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
3155                 return;
3156         }
3157
3158         val = CallIntMethod(env, refcount, intvalue);
3159         val--;
3160
3161         if (val == 0) {
3162                 CallObjectMethod(env, *global_ref_table, removemid,refcount);
3163
3164         } else {
3165                 jobject newval = NewObject(env, intclass, newint, val);
3166
3167                 if (newval != NULL) {
3168                         CallObjectMethod(env,*global_ref_table, putmid,newval);
3169
3170                 } else {
3171                         log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
3172                 }
3173         }
3174
3175         MonitorExit(env,*global_ref_table);
3176 }
3177
3178
3179 /* ExceptionCheck *****************************************************************
3180
3181    check for pending exception
3182
3183 **********************************************************************************/
3184
3185 jboolean ExceptionCheck(JNIEnv *env)
3186 {
3187         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3188 }
3189
3190
3191 /* New JNI 1.4 functions ******************************************************/
3192
3193 /* NewDirectByteBuffer *********************************************************
3194
3195    Allocates and returns a direct java.nio.ByteBuffer referring to the block of
3196    memory starting at the memory address address and extending capacity bytes.
3197
3198 *******************************************************************************/
3199
3200 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3201 {
3202         log_text("NewDirectByteBuffer: IMPLEMENT ME!");
3203
3204         return NULL;
3205 }
3206
3207
3208 /* GetDirectBufferAddress ******************************************************
3209
3210    Fetches and returns the starting address of the memory region referenced by
3211    the given direct java.nio.Buffer.
3212
3213 *******************************************************************************/
3214
3215 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
3216 {
3217         log_text("GetDirectBufferAddress: IMPLEMENT ME!");
3218
3219         return NULL;
3220 }
3221
3222
3223 /* GetDirectBufferCapacity *****************************************************
3224
3225    Fetches and returns the capacity in bytes of the memory region referenced by
3226    the given direct java.nio.Buffer.
3227
3228 *******************************************************************************/
3229
3230 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3231 {
3232         log_text("GetDirectBufferCapacity: IMPLEMENT ME!");
3233
3234         return 0;
3235 }
3236
3237
3238 jint DestroyJavaVM(JavaVM *vm)
3239 {
3240         log_text("DestroyJavaVM called");
3241
3242         return 0;
3243 }
3244
3245
3246 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3247 {
3248         log_text("AttachCurrentThread called");
3249
3250         return 0;
3251 }
3252
3253
3254 jint DetachCurrentThread(JavaVM *vm)
3255 {
3256         log_text("DetachCurrentThread called");
3257
3258         return 0;
3259 }
3260
3261
3262 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3263 {
3264         *environment = &JNI_envTable;
3265
3266         return 0;
3267 }
3268
3269
3270 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3271 {
3272         log_text("AttachCurrentThreadAsDaemon called");
3273
3274         return 0;
3275 }
3276
3277 /************* JNI Initialization ****************************************************/
3278
3279 jobject jni_init1(JNIEnv* env, jobject lobj) {
3280 #if defined(USE_THREADS)
3281         while (initrunning) {yieldThread();} /* wait until init is done */
3282 #endif
3283         if (global_ref_table == NULL) {
3284                 jni_init();
3285         } 
3286 #if defined(USE_THREADS)
3287         else {
3288                 /* wait until jni_init is done */
3289                 MonitorEnter(env, *global_ref_table) ;
3290                 MonitorExit(env, *global_ref_table);
3291         }
3292 #endif
3293         return NewGlobalRef(env, lobj); 
3294 }
3295 void jni_init2(JNIEnv* env, jobject gref) {
3296         log_text("DeleteGlobalref called before NewGlobalref");
3297 #if defined(USE_THREADS)
3298         while (initrunning) {yieldThread();} /* wait until init is done */
3299 #endif
3300         if (global_ref_table == NULL) {
3301                 jni_init();
3302         } 
3303 #if defined(USE_THREADS)
3304         else {
3305                 /* wait until jni_init is done */
3306                 MonitorEnter(env, *global_ref_table) ;
3307                 MonitorExit(env, *global_ref_table);
3308         }
3309 #endif
3310         DeleteGlobalRef(env, gref); 
3311 }
3312
3313 void jni_init(){
3314         jmethodID mid;
3315
3316         initrunning = true;
3317         log_text("JNI-Init: initialize global_ref_table");
3318         /* initalize global reference table */
3319         ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
3320         
3321         if (ihmclass == NULL) {
3322                 log_text("JNI-Init: unable to find java.util.IdentityHashMap");
3323         }
3324
3325         mid = GetMethodID(NULL, ihmclass, "<init>","()V");
3326         if (mid == NULL) {
3327                 log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
3328         }
3329         
3330         global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
3331
3332         *global_ref_table = NewObject(NULL,ihmclass,mid);
3333
3334         if (*global_ref_table == NULL) {
3335                 log_text("JNI-Init: unable to create new global_ref_table");
3336         }
3337
3338         initrunning = false;
3339
3340         getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3341         if (mid == NULL) {
3342                 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3343         }
3344
3345         getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
3346         if (getmid == NULL) {
3347                 log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
3348         }
3349
3350         putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
3351         if (putmid == NULL) {
3352                 log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
3353         }
3354
3355         intclass = FindClass(NULL, "java/lang/Integer");
3356         if (intclass == NULL) {
3357                 log_text("JNI-Init: unable to find java.lang.Integer");
3358         }
3359
3360         newint = GetMethodID(NULL, intclass, "<init>","(I)V");
3361         if (newint == NULL) {
3362                 log_text("JNI-Init: unable to find constructor in java.lang.Integer");
3363         }
3364
3365         intvalue = GetMethodID(NULL, intclass, "intValue","()I");
3366         if (intvalue == NULL) {
3367                 log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
3368         }
3369
3370         removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
3371         if (removemid == NULL) {
3372                 log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
3373         }
3374         
3375         /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
3376
3377         JNI_envTable.NewGlobalRef = &NewGlobalRef;
3378         JNI_envTable.DeleteGlobalRef = &DeleteGlobalRef;
3379 }
3380
3381
3382 /* JNI invocation table *******************************************************/
3383
3384 struct _JavaVM JNI_javaVMTable = {
3385         NULL,
3386         NULL,
3387         NULL,
3388         &DestroyJavaVM,
3389         &AttachCurrentThread,
3390         &DetachCurrentThread,
3391         &GetEnv,
3392         &AttachCurrentThreadAsDaemon
3393 };
3394
3395
3396 /* JNI function table *********************************************************/
3397
3398 struct JNI_Table JNI_envTable = {
3399         NULL,
3400         NULL,
3401         NULL,
3402         NULL,    
3403         &GetVersion,
3404
3405         &DefineClass,
3406         &FindClass,
3407         &FromReflectedMethod,
3408         &FromReflectedField,
3409         &ToReflectedMethod,
3410         &GetSuperclass,
3411         &IsAssignableFrom,
3412         &ToReflectedField,
3413
3414         &Throw,
3415         &ThrowNew,
3416         &ExceptionOccurred,
3417         &ExceptionDescribe,
3418         &ExceptionClear,
3419         &FatalError,
3420         &PushLocalFrame,
3421         &PopLocalFrame,
3422
3423         &jni_init1, /* &NewGlobalRef,    initialize Global_Ref_Table*/
3424         &jni_init2, /* &DeleteGlobalRef,*/
3425         &DeleteLocalRef,
3426         &IsSameObject,
3427         &NewLocalRef,
3428         &EnsureLocalCapacity,
3429
3430         &AllocObject,
3431         &NewObject,
3432         &NewObjectV,
3433         &NewObjectA,
3434
3435         &GetObjectClass,
3436         &IsInstanceOf,
3437
3438         &GetMethodID,
3439
3440         &CallObjectMethod,
3441         &CallObjectMethodV,
3442         &CallObjectMethodA,
3443         &CallBooleanMethod,
3444         &CallBooleanMethodV,
3445         &CallBooleanMethodA,
3446         &CallByteMethod,
3447         &CallByteMethodV,
3448         &CallByteMethodA,
3449         &CallCharMethod,
3450         &CallCharMethodV,
3451         &CallCharMethodA,
3452         &CallShortMethod,
3453         &CallShortMethodV,
3454         &CallShortMethodA,
3455         &CallIntMethod,
3456         &CallIntMethodV,
3457         &CallIntMethodA,
3458         &CallLongMethod,
3459         &CallLongMethodV,
3460         &CallLongMethodA,
3461         &CallFloatMethod,
3462         &CallFloatMethodV,
3463         &CallFloatMethodA,
3464         &CallDoubleMethod,
3465         &CallDoubleMethodV,
3466         &CallDoubleMethodA,
3467         &CallVoidMethod,
3468         &CallVoidMethodV,
3469         &CallVoidMethodA,
3470
3471         &CallNonvirtualObjectMethod,
3472         &CallNonvirtualObjectMethodV,
3473         &CallNonvirtualObjectMethodA,
3474         &CallNonvirtualBooleanMethod,
3475         &CallNonvirtualBooleanMethodV,
3476         &CallNonvirtualBooleanMethodA,
3477         &CallNonvirtualByteMethod,
3478         &CallNonvirtualByteMethodV,
3479         &CallNonvirtualByteMethodA,
3480         &CallNonvirtualCharMethod,
3481         &CallNonvirtualCharMethodV,
3482         &CallNonvirtualCharMethodA,
3483         &CallNonvirtualShortMethod,
3484         &CallNonvirtualShortMethodV,
3485         &CallNonvirtualShortMethodA,
3486         &CallNonvirtualIntMethod,
3487         &CallNonvirtualIntMethodV,
3488         &CallNonvirtualIntMethodA,
3489         &CallNonvirtualLongMethod,
3490         &CallNonvirtualLongMethodV,
3491         &CallNonvirtualLongMethodA,
3492         &CallNonvirtualFloatMethod,
3493         &CallNonvirtualFloatMethodV,
3494         &CallNonvirtualFloatMethodA,
3495         &CallNonvirtualDoubleMethod,
3496         &CallNonvirtualDoubleMethodV,
3497         &CallNonvirtualDoubleMethodA,
3498         &CallNonvirtualVoidMethod,
3499         &CallNonvirtualVoidMethodV,
3500         &CallNonvirtualVoidMethodA,
3501
3502         &GetFieldID,
3503
3504         &GetObjectField,
3505         &GetBooleanField,
3506         &GetByteField,
3507         &GetCharField,
3508         &GetShortField,
3509         &GetIntField,
3510         &GetLongField,
3511         &GetFloatField,
3512         &GetDoubleField,
3513         &SetObjectField,
3514         &SetBooleanField,
3515         &SetByteField,
3516         &SetCharField,
3517         &SetShortField,
3518         &SetIntField,
3519         &SetLongField,
3520         &SetFloatField,
3521         &SetDoubleField,
3522
3523         &GetStaticMethodID,
3524
3525         &CallStaticObjectMethod,
3526         &CallStaticObjectMethodV,
3527         &CallStaticObjectMethodA,
3528         &CallStaticBooleanMethod,
3529         &CallStaticBooleanMethodV,
3530         &CallStaticBooleanMethodA,
3531         &CallStaticByteMethod,
3532         &CallStaticByteMethodV,
3533         &CallStaticByteMethodA,
3534         &CallStaticCharMethod,
3535         &CallStaticCharMethodV,
3536         &CallStaticCharMethodA,
3537         &CallStaticShortMethod,
3538         &CallStaticShortMethodV,
3539         &CallStaticShortMethodA,
3540         &CallStaticIntMethod,
3541         &CallStaticIntMethodV,
3542         &CallStaticIntMethodA,
3543         &CallStaticLongMethod,
3544         &CallStaticLongMethodV,
3545         &CallStaticLongMethodA,
3546         &CallStaticFloatMethod,
3547         &CallStaticFloatMethodV,
3548         &CallStaticFloatMethodA,
3549         &CallStaticDoubleMethod,
3550         &CallStaticDoubleMethodV,
3551         &CallStaticDoubleMethodA,
3552         &CallStaticVoidMethod,
3553         &CallStaticVoidMethodV,
3554         &CallStaticVoidMethodA,
3555
3556         &GetStaticFieldID,
3557
3558         &GetStaticObjectField,
3559         &GetStaticBooleanField,
3560         &GetStaticByteField,
3561         &GetStaticCharField,
3562         &GetStaticShortField,
3563         &GetStaticIntField,
3564         &GetStaticLongField,
3565         &GetStaticFloatField,
3566         &GetStaticDoubleField,
3567         &SetStaticObjectField,
3568         &SetStaticBooleanField,
3569         &SetStaticByteField,
3570         &SetStaticCharField,
3571         &SetStaticShortField,
3572         &SetStaticIntField,
3573         &SetStaticLongField,
3574         &SetStaticFloatField,
3575         &SetStaticDoubleField,
3576
3577         &NewString,
3578         &GetStringLength,
3579         &GetStringChars,
3580         &ReleaseStringChars,
3581
3582         &NewStringUTF,
3583         &GetStringUTFLength,
3584         &GetStringUTFChars,
3585         &ReleaseStringUTFChars,
3586
3587         &GetArrayLength,
3588
3589         &NewObjectArray,
3590         &GetObjectArrayElement,
3591         &SetObjectArrayElement,
3592
3593         &NewBooleanArray,
3594         &NewByteArray,
3595         &NewCharArray,
3596         &NewShortArray,
3597         &NewIntArray,
3598         &NewLongArray,
3599         &NewFloatArray,
3600         &NewDoubleArray,
3601
3602         &GetBooleanArrayElements,
3603         &GetByteArrayElements,
3604         &GetCharArrayElements,
3605         &GetShortArrayElements,
3606         &GetIntArrayElements,
3607         &GetLongArrayElements,
3608         &GetFloatArrayElements,
3609         &GetDoubleArrayElements,
3610
3611         &ReleaseBooleanArrayElements,
3612         &ReleaseByteArrayElements,
3613         &ReleaseCharArrayElements,
3614         &ReleaseShortArrayElements,
3615         &ReleaseIntArrayElements,
3616         &ReleaseLongArrayElements,
3617         &ReleaseFloatArrayElements,
3618         &ReleaseDoubleArrayElements,
3619
3620         &GetBooleanArrayRegion,
3621         &GetByteArrayRegion,
3622         &GetCharArrayRegion,
3623         &GetShortArrayRegion,
3624         &GetIntArrayRegion,
3625         &GetLongArrayRegion,
3626         &GetFloatArrayRegion,
3627         &GetDoubleArrayRegion,
3628         &SetBooleanArrayRegion,
3629         &SetByteArrayRegion,
3630         &SetCharArrayRegion,
3631         &SetShortArrayRegion,
3632         &SetIntArrayRegion,
3633         &SetLongArrayRegion,
3634         &SetFloatArrayRegion,
3635         &SetDoubleArrayRegion,
3636
3637         &RegisterNatives,
3638         &UnregisterNatives,
3639
3640         &MonitorEnter,
3641         &MonitorExit,
3642
3643         &GetJavaVM,
3644
3645         /* new JNI 1.2 functions */
3646
3647         &GetStringRegion,
3648         &GetStringUTFRegion,
3649
3650         &GetPrimitiveArrayCritical,
3651         &ReleasePrimitiveArrayCritical,
3652
3653         &GetStringCritical,
3654         &ReleaseStringCritical,
3655
3656         &NewWeakGlobalRef,
3657         &DeleteWeakGlobalRef,
3658
3659         &ExceptionCheck,
3660
3661         /* new JNI 1.4 functions */
3662
3663         &NewDirectByteBuffer,
3664         &GetDirectBufferAddress,
3665         &GetDirectBufferCapacity
3666 };
3667
3668
3669 /* Invocation API Functions ***************************************************/
3670
3671 /* JNI_GetDefaultJavaVMInitArgs ************************************************
3672
3673    Returns a default configuration for the Java VM.
3674
3675 *******************************************************************************/
3676
3677 jint JNI_GetDefaultJavaVMInitArgs(void *p_vm_args)
3678 {
3679         JDK1_1InitArgs *vm_args = (JDK1_1InitArgs *) p_vm_args;
3680
3681         /* GNU classpath currently supports JNI 1.2 */
3682
3683         vm_args->version = JNI_VERSION_1_2;
3684
3685         return 0;
3686 }
3687
3688
3689 /* JNI_GetCreatedJavaVMs *******************************************************
3690
3691    Returns all Java VMs that have been created. Pointers to VMs are written in
3692    the buffer vmBuf in the order they are created. At most bufLen number of
3693    entries will be written. The total number of created VMs is returned in
3694    *nVMs.
3695
3696 *******************************************************************************/
3697
3698 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
3699 {
3700         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
3701 }
3702
3703
3704 /* JNI_CreateJavaVM ************************************************************
3705
3706    Loads and initializes a Java VM. The current thread becomes the main thread.
3707    Sets the env argument to the JNI interface pointer of the main thread.
3708
3709 *******************************************************************************/
3710
3711 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *p_vm_args)
3712 {
3713         *p_vm = &JNI_javaVMTable;
3714         *p_env = &JNI_envTable;
3715
3716         return 0;
3717 }
3718
3719
3720 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3721 {
3722         int argcount;
3723         jni_callblock *blk;
3724         char retT;
3725         jobject retVal;
3726
3727         if (methodID == 0) {
3728                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
3729                 return NULL;
3730         }
3731
3732         argcount = get_parametercount(methodID);
3733
3734         if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3735                 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3736                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3737                 return 0;
3738         }
3739
3740
3741 #ifdef arglimit
3742         if (argcount > 3) {
3743                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3744                 log_text("Too many arguments. invokeNativeHelper does not support that");
3745                 return 0;
3746         }
3747 #endif
3748         if (((params==0) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3749                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3750                 return 0;
3751         }
3752
3753
3754         if (((methodID->flags & ACC_STATIC)==0) && (0==obj))  {
3755                 *exceptionptr =
3756                         new_exception_message(string_java_lang_NullPointerException,
3757                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3758                 return 0;
3759         }
3760
3761         if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3762
3763         if (obj) {
3764                 if ( (methodID->flags & ACC_ABSTRACT) || (methodID->class->flags & ACC_INTERFACE) ) {
3765                         methodID=get_virtual(obj,methodID);
3766                 }
3767         }
3768
3769         blk = MNEW(jni_callblock, /*4 */argcount+2);
3770
3771         retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3772
3773         switch (retT) {
3774         case 'V':
3775                 (void) asm_calljavafunction2(methodID,
3776                                                                          argcount + 1,
3777                                                                          (argcount + 1) * sizeof(jni_callblock),
3778                                                                          blk);
3779                 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3780                 break;
3781
3782         case 'I': {
3783                 s4 intVal;
3784                 intVal = asm_calljavafunction2int(methodID,
3785                                                                                   argcount + 1,
3786                                                                                   (argcount + 1) * sizeof(jni_callblock),
3787                                                                                   blk);
3788                 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3789                 CallVoidMethod(env,
3790                                            retVal,
3791                                            class_resolvemethod(retVal->vftbl->class,
3792                                                                                    utf_new_char("<init>"),
3793                                                                                    utf_new_char("(I)V")),
3794                                            intVal);
3795         }
3796         break;
3797
3798         case 'B': {
3799                 s4 intVal;
3800                 intVal = asm_calljavafunction2int(methodID,
3801                                                                                   argcount + 1,
3802                                                                                   (argcount + 1) * sizeof(jni_callblock),
3803                                                                                   blk);
3804                 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3805                 CallVoidMethod(env,
3806                                            retVal,
3807                                            class_resolvemethod(retVal->vftbl->class,
3808                                                                                    utf_new_char("<init>"),
3809                                                                                    utf_new_char("(B)V")),
3810                                            intVal);
3811         }
3812         break;
3813
3814         case 'C': {
3815                 s4 intVal;
3816                 intVal = asm_calljavafunction2int(methodID,
3817                                                                                   argcount + 1,
3818                                                                                   (argcount + 1) * sizeof(jni_callblock),
3819                                                                                   blk);
3820                 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3821                 CallVoidMethod(env,
3822                                            retVal,
3823                                            class_resolvemethod(retVal->vftbl->class,
3824                                                                                    utf_new_char("<init>"),
3825                                                                                    utf_new_char("(C)V")),
3826                                            intVal);
3827         }
3828         break;
3829
3830         case 'S': {
3831                 s4 intVal;
3832                 intVal = asm_calljavafunction2int(methodID,
3833                                                                                   argcount + 1,
3834                                                                                   (argcount + 1) * sizeof(jni_callblock),
3835                                                                                   blk);
3836                 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3837                 CallVoidMethod(env,
3838                                            retVal,
3839                                            class_resolvemethod(retVal->vftbl->class,
3840                                                                                    utf_new_char("<init>"),
3841                                                                                    utf_new_char("(S)V")),
3842                                            intVal);
3843         }
3844         break;
3845
3846         case 'Z': {
3847                 s4 intVal;
3848                 intVal = asm_calljavafunction2int(methodID,
3849                                                                                   argcount + 1,
3850                                                                                   (argcount + 1) * sizeof(jni_callblock),
3851                                                                                   blk);
3852                 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3853                 CallVoidMethod(env,
3854                                            retVal,
3855                                            class_resolvemethod(retVal->vftbl->class,
3856                                                                                    utf_new_char("<init>"),
3857                                                                                    utf_new_char("(Z)V")),
3858                                            intVal);
3859         }
3860         break;
3861
3862         case 'J': {
3863                 jlong longVal;
3864                 longVal = asm_calljavafunction2long(methodID,
3865                                                                                         argcount + 1,
3866                                                                                         (argcount + 1) * sizeof(jni_callblock),
3867                                                                                         blk);
3868                 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3869                 CallVoidMethod(env,
3870                                            retVal,
3871                                            class_resolvemethod(retVal->vftbl->class,
3872                                                                                    utf_new_char("<init>"),
3873                                                                                    utf_new_char("(J)V")),
3874                                            longVal);
3875         }
3876         break;
3877
3878         case 'F': {
3879                 jdouble floatVal;       
3880                 floatVal = asm_calljavafunction2float(methodID,
3881                                                                                           argcount + 1,
3882                                                                                           (argcount + 1) * sizeof(jni_callblock),
3883                                                                                           blk);
3884                 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3885                 CallVoidMethod(env,
3886                                            retVal,
3887                                            class_resolvemethod(retVal->vftbl->class,
3888                                                                                    utf_new_char("<init>"),
3889                                                                                    utf_new_char("(F)V")),
3890                                            floatVal);
3891         }
3892         break;
3893
3894         case 'D': {
3895                 jdouble doubleVal;
3896                 doubleVal = asm_calljavafunction2double(methodID,
3897                                                                                                 argcount + 1,
3898                                                                                                 (argcount + 1) * sizeof(jni_callblock),
3899                                                                                                 blk);
3900                 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3901                 CallVoidMethod(env,
3902                                            retVal,
3903                                            class_resolvemethod(retVal->vftbl->class,
3904                                                                                    utf_new_char("<init>"),
3905                                                                                    utf_new_char("(D)V")),
3906                                            doubleVal);
3907         }
3908         break;
3909
3910         case 'L': /* fall through */
3911         case '[':
3912                 retVal = asm_calljavafunction2(methodID,
3913                                                                            argcount + 1,
3914                                                                            (argcount + 1) * sizeof(jni_callblock),
3915                                                                            blk);
3916                 break;
3917
3918         default:
3919                 /* if this happens the acception has already been set by fill_callblock_objA*/
3920                 MFREE(blk, jni_callblock, /*4 */ argcount+2);
3921                 return (jobject *) 0;
3922         }
3923
3924         MFREE(blk, jni_callblock, /* 4 */ argcount+2);
3925
3926         if (*exceptionptr) {
3927                 java_objectheader *exceptionToWrap = *exceptionptr;
3928                 classinfo *ivtec;
3929                 java_objectheader *ivte;
3930
3931                 *exceptionptr = NULL;
3932                 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3933                 ivte = builtin_new(ivtec);
3934                 asm_calljavafunction(class_resolvemethod(ivtec,
3935                                                                                                  utf_new_char("<init>"),
3936                                                                                                  utf_new_char("(Ljava/lang/Throwable;)V")),
3937                                                          ivte,
3938                                                          exceptionToWrap,
3939                                                          0,
3940                                                          0);
3941
3942                 if (*exceptionptr != NULL)
3943                         panic("jni.c: error while creating InvocationTargetException wrapper");
3944
3945                 *exceptionptr = ivte;
3946         }
3947
3948         return (jobject *) retVal;
3949 }
3950
3951
3952
3953
3954 /*
3955  * These are local overrides for various environment variables in Emacs.
3956  * Please do not remove this and leave it at the end of the file, where
3957  * Emacs will automagically detect them.
3958  * ---------------------------------------------------------------------
3959  * Local variables:
3960  * mode: c
3961  * indent-tabs-mode: t
3962  * c-basic-offset: 4
3963  * tab-width: 4
3964  * End:
3965  */