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