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