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