Removed offsets.h stuff.
[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 1173 2004-06-16 14:56:18Z 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         jobject ret;
1931         va_list vaargs;
1932
1933         /* log_text("JNI-Call: CallStaticObjectMethod");*/
1934
1935         va_start(vaargs, methodID);
1936         ret = callObjectMethod(0, methodID, vaargs);
1937         va_end(vaargs);
1938
1939         return ret;
1940 }
1941
1942
1943 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1944 {
1945         /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1946         
1947         return callObjectMethod(0,methodID,args);
1948 }
1949
1950
1951 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1952 {
1953         log_text("JNI-Call: CallStaticObjectMethodA");
1954
1955         return NULL;
1956 }
1957
1958
1959 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1960 {
1961         jboolean ret;
1962         va_list vaargs;
1963
1964         va_start(vaargs, methodID);
1965         ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
1966         va_end(vaargs);
1967
1968         return ret;
1969 }
1970
1971
1972 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1973 {
1974         return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
1975 }
1976
1977
1978 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1979 {
1980         log_text("JNI-Call: CallStaticBooleanMethodA");
1981
1982         return 0;
1983 }
1984
1985
1986 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1987 {
1988         jbyte ret;
1989         va_list vaargs;
1990
1991         /*      log_text("JNI-Call: CallStaticByteMethod");*/
1992
1993         va_start(vaargs, methodID);
1994         ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
1995         va_end(vaargs);
1996
1997         return ret;
1998 }
1999
2000
2001 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2002 {
2003         return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2004 }
2005
2006
2007 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2008 {
2009         log_text("JNI-Call: CallStaticByteMethodA");
2010
2011         return 0;
2012 }
2013
2014
2015 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2016 {
2017         jchar ret;
2018         va_list vaargs;
2019
2020         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2021
2022         va_start(vaargs, methodID);
2023         ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2024         va_end(vaargs);
2025
2026         return ret;
2027 }
2028
2029
2030 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2031 {
2032         return (jchar) callIntegerMethod(0, methodID, 'C', args);
2033 }
2034
2035
2036 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2037 {
2038         log_text("JNI-Call: CallStaticCharMethodA");
2039
2040         return 0;
2041 }
2042
2043
2044
2045 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2046 {
2047         jshort ret;
2048         va_list vaargs;
2049
2050         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2051
2052         va_start(vaargs, methodID);
2053         ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2054         va_end(vaargs);
2055
2056         return ret;
2057 }
2058
2059
2060 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2061 {
2062         /*log_text("JNI-Call: CallStaticShortMethodV");*/
2063         return (jshort) callIntegerMethod(0, methodID, 'S', args);
2064 }
2065
2066
2067 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2068 {
2069         log_text("JNI-Call: CallStaticShortMethodA");
2070
2071         return 0;
2072 }
2073
2074
2075
2076 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2077 {
2078         jint ret;
2079         va_list vaargs;
2080
2081         /*      log_text("JNI-Call: CallStaticIntMethod");*/
2082
2083         va_start(vaargs, methodID);
2084         ret = callIntegerMethod(0, methodID, 'I', vaargs);
2085         va_end(vaargs);
2086
2087         return ret;
2088 }
2089
2090
2091 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2092 {
2093         log_text("JNI-Call: CallStaticIntMethodV");
2094
2095         return callIntegerMethod(0, methodID, 'I', args);
2096 }
2097
2098
2099 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2100 {
2101         log_text("JNI-Call: CallStaticIntMethodA");
2102
2103         return 0;
2104 }
2105
2106
2107
2108 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2109 {
2110         jlong ret;
2111         va_list vaargs;
2112
2113         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2114
2115         va_start(vaargs, methodID);
2116         ret = callLongMethod(0, methodID, vaargs);
2117         va_end(vaargs);
2118
2119         return ret;
2120 }
2121
2122
2123 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2124 {
2125         log_text("JNI-Call: CallStaticLongMethodV");
2126         
2127         return callLongMethod(0,methodID,args);
2128 }
2129
2130
2131 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2132 {
2133         log_text("JNI-Call: CallStaticLongMethodA");
2134
2135         return 0;
2136 }
2137
2138
2139
2140 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2141 {
2142         jfloat ret;
2143         va_list vaargs;
2144
2145         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2146
2147         va_start(vaargs, methodID);
2148         ret = callFloatMethod(0, methodID, vaargs, 'F');
2149         va_end(vaargs);
2150
2151         return ret;
2152 }
2153
2154
2155 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2156 {
2157
2158         return callFloatMethod(0, methodID, args, 'F');
2159
2160 }
2161
2162
2163 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2164 {
2165         log_text("JNI-Call: CallStaticFloatMethodA");
2166
2167         return 0;
2168 }
2169
2170
2171
2172 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2173 {
2174         jdouble ret;
2175         va_list vaargs;
2176
2177         /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
2178
2179         va_start(vaargs,methodID);
2180         ret = callFloatMethod(0, methodID, vaargs, 'D');
2181         va_end(vaargs);
2182
2183         return ret;
2184 }
2185
2186
2187 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2188 {
2189         log_text("JNI-Call: CallStaticDoubleMethodV");
2190
2191         return callFloatMethod(0, methodID, args, 'D');
2192 }
2193
2194
2195 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2196 {
2197         log_text("JNI-Call: CallStaticDoubleMethodA");
2198
2199         return 0;
2200 }
2201
2202
2203 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2204 {
2205         va_list vaargs;
2206
2207 /*      log_text("JNI-Call: CallStaticVoidMethod");*/
2208
2209         va_start(vaargs, methodID);
2210         (void) callIntegerMethod(0, methodID, 'V', vaargs);
2211         va_end(vaargs);
2212 }
2213
2214
2215 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2216 {
2217         log_text("JNI-Call: CallStaticVoidMethodV");
2218         (void)callIntegerMethod(0, methodID, 'V', args);
2219 }
2220
2221
2222 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2223 {
2224         log_text("JNI-Call: CallStaticVoidMethodA");
2225 }
2226
2227
2228 /****************** JNI-functions for accessing static fields ********************/
2229
2230 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
2231 {
2232         jfieldID f;
2233
2234         f = jclass_findfield(clazz,
2235                             utf_new_char ((char*) name), 
2236                             utf_new_char ((char*) sig)
2237                             ); 
2238         
2239         if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2240
2241         return f;
2242 }
2243
2244
2245 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2246 {
2247         class_init(clazz);
2248         return fieldID->value.a;       
2249 }
2250
2251
2252 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2253 {
2254         class_init(clazz);
2255         return fieldID->value.i;       
2256 }
2257
2258
2259 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2260 {
2261         class_init(clazz);
2262         return fieldID->value.i;       
2263 }
2264
2265
2266 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2267 {
2268         class_init(clazz);
2269         return fieldID->value.i;       
2270 }
2271
2272
2273 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2274 {
2275         class_init(clazz);
2276         return fieldID->value.i;       
2277 }
2278
2279
2280 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2281 {
2282         class_init(clazz);
2283         return fieldID->value.i;       
2284 }
2285
2286
2287 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2288 {
2289         class_init(clazz);
2290         return fieldID->value.l;
2291 }
2292
2293
2294 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2295 {
2296         class_init(clazz);
2297         return fieldID->value.f;
2298 }
2299
2300
2301 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2302 {
2303         class_init(clazz);
2304         return fieldID->value.d;
2305 }
2306
2307
2308
2309 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2310 {
2311         class_init(clazz);
2312         fieldID->value.a = value;
2313 }
2314
2315
2316 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2317 {
2318         class_init(clazz);
2319         fieldID->value.i = value;
2320 }
2321
2322
2323 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2324 {
2325         class_init(clazz);
2326         fieldID->value.i = value;
2327 }
2328
2329
2330 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2331 {
2332         class_init(clazz);
2333         fieldID->value.i = value;
2334 }
2335
2336
2337 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2338 {
2339         class_init(clazz);
2340         fieldID->value.i = value;
2341 }
2342
2343
2344 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2345 {
2346         class_init(clazz);
2347         fieldID->value.i = value;
2348 }
2349
2350
2351 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2352 {
2353         class_init(clazz);
2354         fieldID->value.l = value;
2355 }
2356
2357
2358 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2359 {
2360         class_init(clazz);
2361         fieldID->value.f = value;
2362 }
2363
2364
2365 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2366 {
2367         class_init(clazz);
2368         fieldID->value.d = value;
2369 }
2370
2371
2372 /*****  create new java.lang.String object from an array of Unicode characters ****/ 
2373
2374 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2375 {
2376         u4 i;
2377         java_lang_String *s;
2378         java_chararray *a;
2379         
2380         s = (java_lang_String*) builtin_new (class_java_lang_String);
2381         a = builtin_newarray_char (len);
2382
2383         /* javastring or characterarray could not be created */
2384         if ( (!a) || (!s) ) return NULL;
2385
2386         /* copy text */
2387         for (i=0; i<len; i++) a->data[i] = buf[i];
2388         s -> value = a;
2389         s -> offset = 0;
2390         s -> count = len;
2391
2392         return (jstring) s;
2393 }
2394
2395
2396 static char emptyString[]="";
2397 static jchar emptyStringJ[]={0,0};
2398
2399 /******************* returns the length of a Java string ***************************/
2400
2401 jsize GetStringLength (JNIEnv *env, jstring str)
2402 {
2403         return ((java_lang_String*) str)->count;
2404 }
2405
2406
2407 /********************  convertes javastring to u2-array ****************************/
2408         
2409 u2 *javastring_tou2 (jstring so) 
2410 {
2411         java_lang_String *s = (java_lang_String*) so;
2412         java_chararray *a;
2413         u4 i;
2414         u2 *stringbuffer;
2415         
2416         if (!s) return NULL;
2417
2418         a = s->value;
2419         if (!a) return NULL;
2420
2421         /* allocate memory */
2422         stringbuffer = MNEW( u2 , s->count + 1 );
2423
2424         /* copy text */
2425         for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2426         
2427         /* terminate string */
2428         stringbuffer[i] = '\0';
2429
2430         return stringbuffer;
2431 }
2432
2433 /********* returns a pointer to an array of Unicode characters of the string *******/
2434
2435 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2436 {       
2437         jchar *jc=javastring_tou2(str);
2438
2439         if (jc) {
2440                 if (isCopy) *isCopy=JNI_TRUE;
2441                 return jc;
2442         }
2443         if (isCopy) *isCopy=JNI_TRUE;
2444         return emptyStringJ;
2445 }
2446
2447 /**************** native code no longer needs access to chars **********************/
2448
2449 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2450 {
2451         if (chars==emptyStringJ) return;
2452         MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2453 }
2454
2455 /************ create new java.lang.String object from utf8-characterarray **********/
2456
2457 jstring NewStringUTF (JNIEnv *env, const char *utf)
2458 {
2459 /*    log_text("NewStringUTF called");*/
2460     return (jstring) javastring_new(utf_new_char((char *) utf));
2461 }
2462
2463 /****************** returns the utf8 length in bytes of a string *******************/
2464
2465 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2466 {   
2467     java_lang_String *s = (java_lang_String*) string;
2468
2469     return (jsize) u2_utflength(s->value->data, s->count); 
2470 }
2471
2472
2473 /************ converts a Javastring to an array of UTF-8 characters ****************/
2474
2475 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2476 {
2477     utf *u;
2478
2479     u = javastring_toutf((java_lang_String *) string, false);
2480
2481     if (isCopy)
2482                 *isCopy = JNI_FALSE;
2483         
2484     if (u)
2485                 return u->text;
2486
2487     return emptyString;
2488         
2489 }
2490
2491
2492 /***************** native code no longer needs access to utf ***********************/
2493
2494 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2495 {
2496     /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2497         the garbage collector will never get them*/
2498         /*
2499     log_text("JNI-Call: ReleaseStringUTFChars");
2500     utf_display(utf_new_char(chars));
2501         */
2502 }
2503
2504 /************************** array operations ***************************************/
2505
2506 jsize GetArrayLength(JNIEnv *env, jarray array)
2507 {
2508     return array->size;
2509 }
2510
2511
2512 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2513 {
2514         java_objectarray *j;
2515
2516     if (len < 0) {
2517                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2518                 return NULL;
2519     }
2520
2521     j = builtin_anewarray(len, clazz);
2522
2523     return j;
2524 }
2525
2526
2527 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2528 {
2529     jobject j = NULL;
2530
2531     if (index < array->header.size)     
2532                 j = array->data[index];
2533     else
2534                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2535     
2536     return j;
2537 }
2538
2539
2540 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2541 {
2542     if (index >= array->header.size)
2543                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2544
2545     else {
2546                 /* check if the class of value is a subclass of the element class of the array */
2547                 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2548                         *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2549
2550                 else
2551                         array->data[index] = val;
2552     }
2553 }
2554
2555
2556
2557 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2558 {
2559         java_booleanarray *j;
2560
2561     if (len < 0) {
2562                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2563                 return NULL;
2564     }
2565
2566     j = builtin_newarray_boolean(len);
2567
2568     return j;
2569 }
2570
2571
2572 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2573 {
2574         java_bytearray *j;
2575
2576     if (len < 0) {
2577                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2578                 return NULL;
2579     }
2580
2581     j = builtin_newarray_byte(len);
2582
2583     return j;
2584 }
2585
2586
2587 jcharArray NewCharArray(JNIEnv *env, jsize len)
2588 {
2589         java_chararray *j;
2590
2591     if (len < 0) {
2592                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2593                 return NULL;
2594     }
2595
2596     j = builtin_newarray_char(len);
2597
2598     return j;
2599 }
2600
2601
2602 jshortArray NewShortArray(JNIEnv *env, jsize len)
2603 {
2604         java_shortarray *j;
2605
2606     if (len < 0) {
2607                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2608                 return NULL;
2609     }
2610
2611     j = builtin_newarray_short(len);
2612
2613     return j;
2614 }
2615
2616
2617 jintArray NewIntArray(JNIEnv *env, jsize len)
2618 {
2619         java_intarray *j;
2620
2621     if (len < 0) {
2622                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2623                 return NULL;
2624     }
2625
2626     j = builtin_newarray_int(len);
2627
2628     return j;
2629 }
2630
2631
2632 jlongArray NewLongArray(JNIEnv *env, jsize len)
2633 {
2634         java_longarray *j;
2635
2636     if (len < 0) {
2637                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2638                 return NULL;
2639     }
2640
2641     j = builtin_newarray_long(len);
2642
2643     return j;
2644 }
2645
2646
2647 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2648 {
2649         java_floatarray *j;
2650
2651     if (len < 0) {
2652                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2653                 return NULL;
2654     }
2655
2656     j = builtin_newarray_float(len);
2657
2658     return j;
2659 }
2660
2661
2662 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2663 {
2664         java_doublearray *j;
2665
2666     if (len < 0) {
2667                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2668                 return NULL;
2669     }
2670
2671     j = builtin_newarray_double(len);
2672
2673     return j;
2674 }
2675
2676
2677 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2678 {
2679     if (isCopy) *isCopy = JNI_FALSE;
2680     return array->data;
2681 }
2682
2683
2684 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2685 {
2686     if (isCopy) *isCopy = JNI_FALSE;
2687     return array->data;
2688 }
2689
2690
2691 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2692 {
2693     if (isCopy) *isCopy = JNI_FALSE;
2694     return array->data;
2695 }
2696
2697
2698 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2699 {
2700     if (isCopy) *isCopy = JNI_FALSE;
2701     return array->data;
2702 }
2703
2704
2705 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2706 {
2707     if (isCopy) *isCopy = JNI_FALSE;
2708     return array->data;
2709 }
2710
2711
2712 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2713 {
2714     if (isCopy) *isCopy = JNI_FALSE;
2715     return array->data;
2716 }
2717
2718
2719 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2720 {
2721     if (isCopy) *isCopy = JNI_FALSE;
2722     return array->data;
2723 }
2724
2725
2726 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2727 {
2728     if (isCopy) *isCopy = JNI_FALSE;
2729     return array->data;
2730 }
2731
2732
2733
2734 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2735 {
2736     /* empty */
2737 }
2738
2739
2740 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2741 {
2742     /* empty */
2743 }
2744
2745
2746 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2747 {
2748     /* empty */
2749 }
2750
2751
2752 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2753 {
2754     /* empty */
2755 }
2756
2757
2758 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2759 {
2760     /* empty */
2761 }
2762
2763
2764 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2765 {
2766     /* empty */
2767 }
2768
2769
2770 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2771 {
2772     /* empty */
2773 }
2774
2775
2776 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2777 {
2778     /* empty */
2779 }
2780
2781
2782 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2783 {
2784     if (start < 0 || len < 0 || start + len > array->header.size)
2785                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2786
2787     else
2788                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2789 }
2790
2791
2792 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2793 {
2794     if (start < 0 || len < 0 || start + len > array->header.size) 
2795                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2796
2797     else
2798                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2799 }
2800
2801
2802 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2803 {
2804     if (start < 0 || len < 0 || start + len > array->header.size)
2805                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2806
2807     else
2808                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2809 }
2810
2811
2812 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2813 {
2814     if (start < 0 || len < 0 || start + len > array->header.size)
2815                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2816
2817     else        
2818                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2819 }
2820
2821
2822 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2823 {
2824     if (start < 0 || len < 0 || start + len > array->header.size)
2825                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2826
2827     else
2828                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2829 }
2830
2831
2832 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2833 {
2834     if (start < 0 || len < 0 || start + len > array->header.size)
2835                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2836
2837     else
2838                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2839 }
2840
2841
2842 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2843 {
2844     if (start < 0 || len < 0 || start + len > array->header.size)
2845                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2846
2847     else
2848                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2849 }
2850
2851
2852 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2853 {
2854     if (start < 0 || len < 0 || start+len>array->header.size)
2855                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2856
2857     else
2858                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2859 }
2860
2861
2862 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2863 {
2864     if (start < 0 || len < 0 || start + len > array->header.size)
2865                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2866
2867     else
2868                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2869 }
2870
2871
2872 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2873 {
2874     if (start < 0 || len < 0 || start + len > array->header.size)
2875                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2876
2877     else
2878                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2879 }
2880
2881
2882 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2883 {
2884     if (start < 0 || len < 0 || start + len > array->header.size)
2885                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2886
2887     else
2888                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2889
2890 }
2891
2892
2893 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2894 {
2895     if (start < 0 || len < 0 || start + len > array->header.size)
2896                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2897
2898     else
2899                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2900 }
2901
2902
2903 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2904 {
2905     if (start < 0 || len < 0 || start + len > array->header.size)
2906                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2907
2908     else
2909                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2910
2911 }
2912
2913
2914 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2915 {
2916     if (start < 0 || len < 0 || start + len > array->header.size)
2917                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2918
2919     else
2920                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2921
2922 }
2923
2924
2925 void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2926 {
2927     if (start < 0 || len < 0 || start + len > array->header.size)
2928                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2929
2930     else
2931                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2932
2933 }
2934
2935
2936 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2937 {
2938     if (start < 0 || len < 0 || start + len > array->header.size)
2939                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2940
2941     else
2942                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2943 }
2944
2945
2946 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2947 {
2948     log_text("JNI-Call: RegisterNatives");
2949     return 0;
2950 }
2951
2952
2953 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2954 {
2955     log_text("JNI-Call: UnregisterNatives");
2956     return 0;
2957 }
2958
2959 /******************************* monitor operations ********************************/
2960
2961 jint MonitorEnter (JNIEnv* env, jobject obj)
2962 {
2963     builtin_monitorenter(obj);
2964     return 0;
2965 }
2966
2967
2968 jint MonitorExit (JNIEnv* env, jobject obj)
2969 {
2970     builtin_monitorexit(obj);
2971     return 0;
2972 }
2973
2974
2975 /************************************* JavaVM interface ****************************/
2976 #ifdef __cplusplus
2977 #error CPP mode not supported yet
2978 #else
2979 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
2980 {
2981     log_text("JNI-Call: GetJavaVM");
2982     *vm=&javaVM;
2983     return 0;
2984 }
2985 #endif /*__cplusplus*/
2986
2987 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
2988 {
2989     log_text("JNI-Call: GetStringRegion");
2990
2991 }
2992
2993 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
2994 {
2995     log_text("JNI-Call: GetStringUTFRegion");
2996
2997 }
2998
2999 /************** obtain direct pointer to array elements ***********************/
3000
3001 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3002 {
3003         java_objectheader *s = (java_objectheader*) array;
3004         arraydescriptor *desc = s->vftbl->arraydesc;
3005
3006         if (!desc) return NULL;
3007
3008         return ((u1*)s) + desc->dataoffset;
3009 }
3010
3011
3012 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3013 {
3014         log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3015
3016         /* empty */
3017 }
3018
3019 /**** returns a pointer to an array of Unicode characters of the string *******/
3020
3021 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3022 {
3023         log_text("JNI-Call: GetStringCritical");
3024
3025         return GetStringChars(env,string,isCopy);
3026 }
3027
3028 /*********** native code no longer needs access to chars **********************/
3029
3030 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3031 {
3032         log_text("JNI-Call: ReleaseStringCritical");
3033
3034         ReleaseStringChars(env,string,cstring);
3035 }
3036
3037
3038 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3039 {
3040         log_text("JNI-Call: NewWeakGlobalRef");
3041
3042         return obj;
3043 }
3044
3045
3046 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3047 {
3048         log_text("JNI-Call: DeleteWeakGlobalRef");
3049
3050         /* empty */
3051 }
3052
3053
3054 /******************************* check for pending exception ***********************/
3055
3056
3057 jboolean ExceptionCheck(JNIEnv* env)
3058 {
3059         log_text("JNI-Call: ExceptionCheck");
3060
3061         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3062 }
3063
3064
3065
3066
3067
3068
3069 jint DestroyJavaVM(JavaVM *vm)
3070 {
3071         log_text("DestroyJavaVM called");
3072
3073         return 0;
3074 }
3075
3076
3077 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3078 {
3079         log_text("AttachCurrentThread called");
3080
3081         return 0;
3082 }
3083
3084
3085 jint DetachCurrentThread(JavaVM *vm)
3086 {
3087         log_text("DetachCurrentThread called");
3088
3089         return 0;
3090 }
3091
3092
3093 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3094 {
3095         *environment = &env;
3096
3097         return 0;
3098 }
3099
3100
3101 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3102 {
3103         log_text("AttachCurrentThreadAsDaemon called");
3104
3105         return 0;
3106 }
3107
3108
3109 /********************************* JNI invocation table ******************************/
3110
3111 struct _JavaVM javaVMTable={
3112    NULL,
3113    NULL,
3114    NULL,
3115    &DestroyJavaVM,
3116    &AttachCurrentThread,
3117    &DetachCurrentThread,
3118    &GetEnv,
3119    &AttachCurrentThreadAsDaemon
3120 };
3121
3122 JavaVM javaVM = &javaVMTable;
3123
3124
3125 /********************************* JNI function table ******************************/
3126
3127 struct JNI_Table envTable = {   
3128     NULL,
3129     NULL,
3130     NULL,
3131     NULL,    
3132     &GetVersion,
3133     &DefineClass,
3134     &FindClass,
3135     &FromReflectedMethod,
3136     &FromReflectedField,
3137     &ToReflectedMethod,
3138     &GetSuperclass,
3139     &IsAssignableForm,
3140     &ToReflectedField,
3141     &Throw,
3142     &ThrowNew,
3143     &ExceptionOccurred,
3144     &ExceptionDescribe,
3145     &ExceptionClear,
3146     &FatalError,
3147     &PushLocalFrame,
3148     &PopLocalFrame,
3149     &NewGlobalRef,
3150     &DeleteGlobalRef,
3151     &DeleteLocalRef,
3152     &IsSameObject,
3153     &NewLocalRef,
3154     &EnsureLocalCapacity,
3155     &AllocObject,
3156     &NewObject,
3157     &NewObjectV,
3158     &NewObjectA,
3159     &GetObjectClass,
3160     &IsInstanceOf,
3161     &GetMethodID,
3162     &CallObjectMethod,
3163     &CallObjectMethodV,
3164     &CallObjectMethodA,
3165     &CallBooleanMethod,
3166     &CallBooleanMethodV,
3167     &CallBooleanMethodA,
3168     &CallByteMethod,
3169     &CallByteMethodV,
3170     &CallByteMethodA,
3171     &CallCharMethod,
3172     &CallCharMethodV,
3173     &CallCharMethodA,
3174     &CallShortMethod,
3175     &CallShortMethodV,
3176     &CallShortMethodA,
3177     &CallIntMethod,
3178     &CallIntMethodV,
3179     &CallIntMethodA,
3180     &CallLongMethod,
3181     &CallLongMethodV,
3182     &CallLongMethodA,
3183     &CallFloatMethod,
3184     &CallFloatMethodV,
3185     &CallFloatMethodA,
3186     &CallDoubleMethod,
3187     &CallDoubleMethodV,
3188     &CallDoubleMethodA,
3189     &CallVoidMethod,
3190     &CallVoidMethodV,
3191     &CallVoidMethodA,
3192     &CallNonvirtualObjectMethod,
3193     &CallNonvirtualObjectMethodV,
3194     &CallNonvirtualObjectMethodA,
3195     &CallNonvirtualBooleanMethod,
3196     &CallNonvirtualBooleanMethodV,
3197     &CallNonvirtualBooleanMethodA,
3198     &CallNonvirtualByteMethod,
3199     &CallNonvirtualByteMethodV,
3200     &CallNonvirtualByteMethodA,
3201     &CallNonvirtualCharMethod,
3202     &CallNonvirtualCharMethodV,
3203     &CallNonvirtualCharMethodA,
3204     &CallNonvirtualShortMethod,
3205     &CallNonvirtualShortMethodV,
3206     &CallNonvirtualShortMethodA,
3207     &CallNonvirtualIntMethod,
3208     &CallNonvirtualIntMethodV,
3209     &CallNonvirtualIntMethodA,
3210     &CallNonvirtualLongMethod,
3211     &CallNonvirtualLongMethodV,
3212     &CallNonvirtualLongMethodA,
3213     &CallNonvirtualFloatMethod,
3214     &CallNonvirtualFloatMethodV,
3215     &CallNonvirtualFloatMethodA,
3216     &CallNonvirtualDoubleMethod,
3217     &CallNonvirtualDoubleMethodV,
3218     &CallNonvirtualDoubleMethodA,
3219     &CallNonvirtualVoidMethod,
3220     &CallNonvirtualVoidMethodV,
3221     &CallNonvirtualVoidMethodA,
3222     &GetFieldID,
3223     &GetObjectField,
3224     &GetBooleanField,
3225     &GetByteField,
3226     &GetCharField,
3227     &GetShortField,
3228     &GetIntField,
3229     &GetLongField,
3230     &GetFloatField,
3231     &GetDoubleField,
3232     &SetObjectField,
3233     &SetBooleanField,
3234     &SetByteField,
3235     &SetCharField,
3236     &SetShortField,
3237     &SetIntField,
3238     &SetLongField,
3239     &SetFloatField,
3240     &SetDoubleField,
3241     &GetStaticMethodID,
3242     &CallStaticObjectMethod,
3243     &CallStaticObjectMethodV,
3244     &CallStaticObjectMethodA,
3245     &CallStaticBooleanMethod,
3246     &CallStaticBooleanMethodV,
3247     &CallStaticBooleanMethodA,
3248     &CallStaticByteMethod,
3249     &CallStaticByteMethodV,
3250     &CallStaticByteMethodA,
3251     &CallStaticCharMethod,
3252     &CallStaticCharMethodV,
3253     &CallStaticCharMethodA,
3254     &CallStaticShortMethod,
3255     &CallStaticShortMethodV,
3256     &CallStaticShortMethodA,
3257     &CallStaticIntMethod,
3258     &CallStaticIntMethodV,
3259     &CallStaticIntMethodA,
3260     &CallStaticLongMethod,
3261     &CallStaticLongMethodV,
3262     &CallStaticLongMethodA,
3263     &CallStaticFloatMethod,
3264     &CallStaticFloatMethodV,
3265     &CallStaticFloatMethodA,
3266     &CallStaticDoubleMethod,
3267     &CallStaticDoubleMethodV,
3268     &CallStaticDoubleMethodA,
3269     &CallStaticVoidMethod,
3270     &CallStaticVoidMethodV,
3271     &CallStaticVoidMethodA,
3272     &GetStaticFieldID,
3273     &GetStaticObjectField,
3274     &GetStaticBooleanField,
3275     &GetStaticByteField,
3276     &GetStaticCharField,
3277     &GetStaticShortField,
3278     &GetStaticIntField,
3279     &GetStaticLongField,
3280     &GetStaticFloatField,
3281     &GetStaticDoubleField,
3282     &SetStaticObjectField,
3283     &SetStaticBooleanField,
3284     &SetStaticByteField,
3285     &SetStaticCharField,
3286     &SetStaticShortField,
3287     &SetStaticIntField,
3288     &SetStaticLongField,
3289     &SetStaticFloatField,
3290     &SetStaticDoubleField,
3291     &NewString,
3292     &GetStringLength,
3293     &GetStringChars,
3294     &ReleaseStringChars,
3295     &NewStringUTF,
3296     &GetStringUTFLength,
3297     &GetStringUTFChars,
3298     &ReleaseStringUTFChars,
3299     &GetArrayLength,
3300     &NewObjectArray,
3301     &GetObjectArrayElement,
3302     &SetObjectArrayElement,
3303     &NewBooleanArray,
3304     &NewByteArray,
3305     &NewCharArray,
3306     &NewShortArray,
3307     &NewIntArray,
3308     &NewLongArray,
3309     &NewFloatArray,
3310     &NewDoubleArray,
3311     &GetBooleanArrayElements,
3312     &GetByteArrayElements,
3313     &GetCharArrayElements,
3314     &GetShortArrayElements,
3315     &GetIntArrayElements,
3316     &GetLongArrayElements,
3317     &GetFloatArrayElements,
3318     &GetDoubleArrayElements,
3319     &ReleaseBooleanArrayElements,
3320     &ReleaseByteArrayElements,
3321     &ReleaseCharArrayElements,
3322     &ReleaseShortArrayElements,
3323     &ReleaseIntArrayElements,
3324     &ReleaseLongArrayElements,
3325     &ReleaseFloatArrayElements,
3326     &ReleaseDoubleArrayElements,
3327     &GetBooleanArrayRegion,
3328     &GetByteArrayRegion,
3329     &GetCharArrayRegion,
3330     &GetShortArrayRegion,
3331     &GetIntArrayRegion,
3332     &GetLongArrayRegion,
3333     &GetFloatArrayRegion,
3334     &GetDoubleArrayRegion,
3335     &SetBooleanArrayRegion,
3336     &SetByteArrayRegion,
3337     &SetCharArrayRegion,
3338     &SetShortArrayRegion,
3339     &SetIntArrayRegion,
3340     &SetLongArrayRegion,
3341     &SetFloatArrayRegion,
3342     &SetDoubleArrayRegion,
3343     &RegisterNatives,
3344     &UnregisterNatives,
3345     &MonitorEnter,
3346     &MonitorExit,
3347     &GetJavaVM,
3348     &GetStringRegion,
3349     &GetStringUTFRegion,
3350     &GetPrimitiveArrayCritical,
3351     &ReleasePrimitiveArrayCritical,
3352     &GetStringCritical,
3353     &ReleaseStringCritical,
3354     &NewWeakGlobalRef,
3355     &DeleteWeakGlobalRef,
3356     &ExceptionCheck
3357 };
3358
3359 JNIEnv env = &envTable;
3360
3361
3362 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3363 {
3364         int argcount;
3365         jni_callblock *blk;
3366         char retT;
3367         jobject retVal;
3368
3369         if (methodID == 0) {
3370                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
3371                 return NULL;
3372         }
3373
3374         argcount = get_parametercount(methodID);
3375
3376         if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3377                 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3378                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3379                 return 0;
3380         }
3381
3382
3383
3384         if (argcount > 3) {
3385                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3386                 log_text("Too many arguments. invokeNativeHelper does not support that");
3387                 return 0;
3388         }
3389
3390         if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3391                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3392                 return 0;
3393         }
3394
3395
3396         if (!(methodID->flags & ACC_STATIC) && (!obj))  {
3397                 *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
3398                                                                                           "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3399                 return 0;
3400         }
3401
3402         if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3403
3404         blk = MNEW(jni_callblock, 4 /*argcount+2*/);
3405
3406         retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3407
3408         switch (retT) {
3409         case 'V':
3410                 (void) asm_calljavafunction2(methodID,
3411                                                                          argcount + 1,
3412                                                                          (argcount + 1) * sizeof(jni_callblock),
3413                                                                          blk);
3414                 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3415                 break;
3416
3417         case 'I': {
3418                 s4 intVal;      
3419                 intVal = (s4) asm_calljavafunction2(methodID,
3420                                                                                         argcount + 1,
3421                                                                                         (argcount + 1) * sizeof(jni_callblock),
3422                                                                                         blk);
3423                 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3424                 CallVoidMethod(env,
3425                                            retVal,
3426                                            class_resolvemethod(retVal->vftbl->class,
3427                                                                                    utf_new_char("<init>"),
3428                                                                                    utf_new_char("(I)V")),
3429                                            intVal);
3430         }
3431         break;
3432
3433         case 'B': {
3434                 s4 intVal;      
3435                 intVal = (s4) asm_calljavafunction2(methodID,
3436                                                                                         argcount + 1,
3437                                                                                         (argcount + 1) * sizeof(jni_callblock),
3438                                                                                         blk);
3439                 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3440                 CallVoidMethod(env,
3441                                            retVal,
3442                                            class_resolvemethod(retVal->vftbl->class,
3443                                                                                    utf_new_char("<init>"),
3444                                                                                    utf_new_char("(B)V")),
3445                                            intVal);
3446         }
3447         break;
3448
3449         case 'C': {
3450                 s4 intVal;      
3451                 intVal = (s4) asm_calljavafunction2(methodID,
3452                                                                                         argcount + 1,
3453                                                                                         (argcount + 1) * sizeof(jni_callblock),
3454                                                                                         blk);
3455                 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3456                 CallVoidMethod(env,
3457                                            retVal,
3458                                            class_resolvemethod(retVal->vftbl->class,
3459                                                                                    utf_new_char("<init>"),
3460                                                                                    utf_new_char("(C)V")),
3461                                            intVal);
3462         }
3463         break;
3464
3465         case 'S': {
3466                 s4 intVal;      
3467                 intVal = (s4) asm_calljavafunction2(methodID,
3468                                                                                         argcount + 1,
3469                                                                                         (argcount + 1) * sizeof(jni_callblock),
3470                                                                                         blk);
3471                 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3472                 CallVoidMethod(env,
3473                                            retVal,
3474                                            class_resolvemethod(retVal->vftbl->class,
3475                                                                                    utf_new_char("<init>"),
3476                                                                                    utf_new_char("(S)V")),
3477                                            intVal);
3478         }
3479         break;
3480
3481         case 'Z': {
3482                 s4 intVal;      
3483                 intVal = (s4) asm_calljavafunction2(methodID,
3484                                                                                         argcount + 1,
3485                                                                                         (argcount + 1) * sizeof(jni_callblock),
3486                                                                                         blk);
3487                 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3488                 CallVoidMethod(env,
3489                                            retVal,
3490                                            class_resolvemethod(retVal->vftbl->class,
3491                                                                                    utf_new_char("<init>"),
3492                                                                                    utf_new_char("(Z)V")),
3493                                            intVal);
3494         }
3495         break;
3496
3497         case 'J': {
3498                 jlong intVal;   
3499                 intVal = asm_calljavafunction2long(methodID,
3500                                                                                    argcount + 1,
3501                                                                                    (argcount + 1) * sizeof(jni_callblock),
3502                                                                                    blk);
3503                 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3504                 CallVoidMethod(env,
3505                                            retVal,
3506                                            class_resolvemethod(retVal->vftbl->class,
3507                                                                                    utf_new_char("<init>"),
3508                                                                                    utf_new_char("(J)V")),
3509                                            intVal);
3510         }
3511         break;
3512
3513         case 'F': {
3514                 jdouble floatVal;       
3515                 floatVal = asm_calljavafunction2double(methodID,
3516                                                                                            argcount + 1,
3517                                                                                            (argcount + 1) * sizeof(jni_callblock),
3518                                                                                            blk);
3519                 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3520                 CallVoidMethod(env,
3521                                            retVal,
3522                                            class_resolvemethod(retVal->vftbl->class,
3523                                                                                    utf_new_char("<init>"),
3524                                                                                    utf_new_char("(F)V")),
3525                                            floatVal);
3526         }
3527         break;
3528
3529         case 'D': {
3530                 jdouble floatVal;       
3531                 floatVal = asm_calljavafunction2double(methodID,
3532                                                                                            argcount + 1,
3533                                                                                            (argcount + 1) * sizeof(jni_callblock),
3534                                                                                            blk);
3535                 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3536                 CallVoidMethod(env,
3537                                            retVal,
3538                                            class_resolvemethod(retVal->vftbl->class,
3539                                                                                    utf_new_char("<init>"),
3540                                                                                    utf_new_char("(D)V")),
3541                                            floatVal);
3542         }
3543         break;
3544
3545         case 'L': /* fall through */
3546         case '[':
3547                 retVal = asm_calljavafunction2(methodID,
3548                                                                            argcount + 1,
3549                                                                            (argcount + 1) * sizeof(jni_callblock),
3550                                                                            blk);
3551                 break;
3552
3553         default:
3554                 /* if this happens the acception has already been set by fill_callblock_objA*/
3555                 MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3556                 return (jobject *) 0;
3557         }
3558
3559         MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3560
3561         if (*exceptionptr) {
3562                 java_objectheader *exceptionToWrap = *exceptionptr;
3563                 classinfo *ivtec;
3564                 java_objectheader *ivte;
3565
3566                 *exceptionptr = NULL;
3567                 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3568                 ivte = builtin_new(ivtec);
3569                 asm_calljavafunction(class_resolvemethod(ivtec,
3570                                                                                                  utf_new_char("<init>"),
3571                                                                                                  utf_new_char("(Ljava/lang/Throwable;)V")),
3572                                                          ivte,
3573                                                          exceptionToWrap,
3574                                                          0,
3575                                                          0);
3576
3577                 if (*exceptionptr != NULL)
3578                         panic("jni.c: error while creating InvocationTargetException wrapper");
3579
3580                 *exceptionptr = ivte;
3581         }
3582
3583         return (jobject *) retVal;
3584 }
3585
3586
3587 /*
3588  * These are local overrides for various environment variables in Emacs.
3589  * Please do not remove this and leave it at the end of the file, where
3590  * Emacs will automagically detect them.
3591  * ---------------------------------------------------------------------
3592  * Local variables:
3593  * mode: c
3594  * indent-tabs-mode: t
3595  * c-basic-offset: 4
3596  * tab-width: 4
3597  * End:
3598  */