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