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