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