2c872fe93bbf8182676f702321bcabb8a5811882
[cacao.git] / src / native / jni.c
1 /* jni.c - implementation of the Java Native Interface functions
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: ?
28
29    Changes: Joseph Wenninger
30
31    $Id: jni.c 1328 2004-07-21 14:06:26Z 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, 'L');
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 clazz; 
770         classbuffer *cb;
771         s8 starttime;
772         s8 stoptime;
773
774 #if defined(USE_THREADS)
775 #if defined(NATIVE_THREADS)
776         compiler_lock();
777         tables_lock();
778 #else
779         intsDisable();
780 #endif
781 #endif
782
783         /* measure time */
784         if (getloadingtime)
785                 starttime = getcputime();
786
787         clazz = class_new(utf_new_char((char *) name));
788
789         /* build a classbuffer with the given data */
790         cb = NEW(classbuffer);
791         cb->class = clazz;
792         cb->size = len;
793         cb->data = (u1 *) buf;
794         cb->pos = cb->data - 1;
795
796         class_load_intern(cb);
797
798         /* free memory */
799         FREE(cb, classbuffer);
800
801         /* measure time */
802         if (getloadingtime) {
803                 stoptime = getcputime();
804                 loadingtime += (stoptime - starttime);
805         }
806
807 #if defined(USE_THREADS)
808 #if defined(NATIVE_THREADS)
809         tables_unlock();
810         compiler_unlock();
811 #else
812         intsRestore();
813 #endif
814 #endif
815
816         if (*exceptionptr)
817                 return NULL;
818
819         /* XXX link the class here? */
820         class_link(clazz);
821
822         if (*exceptionptr)
823                 return NULL;
824
825         if (clazz)
826                 clazz->classloader = loader;
827
828         return clazz;
829 }
830
831
832 /*************** loads locally defined class with the specified name **************/
833
834 jclass FindClass(JNIEnv* env, const char *name) 
835 {
836         classinfo *c;  
837   
838         c = class_new(utf_new_char_classname((char *) name));
839
840         class_load(c);
841
842         if (*exceptionptr)
843                 return NULL;
844
845         class_link(c);
846
847         if (*exceptionptr)
848                 return NULL;
849
850         return c;
851 }
852   
853
854 /*********************************************************************************** 
855
856         converts java.lang.reflect.Method or 
857         java.lang.reflect.Constructor object to a method ID  
858   
859  **********************************************************************************/   
860   
861 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
862 {
863         /* log_text("JNI-Call: FromReflectedMethod"); */
864
865         return 0;
866 }
867
868
869 /*************** return superclass of the class represented by sub ****************/
870  
871 jclass GetSuperclass(JNIEnv* env, jclass sub) 
872 {
873         classinfo *c;
874
875         c = ((classinfo*) sub)->super;
876
877         if (!c) return NULL; 
878
879         use_class_as_object(c);
880
881         return c;               
882 }
883   
884  
885 /*********************** check whether sub can be cast to sup  ********************/
886   
887 jboolean IsAssignableForm(JNIEnv* env, jclass sub, jclass sup)
888 {
889         return builtin_isanysubclass(sub, sup);
890 }
891
892
893 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
894
895 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
896 {
897         /* log_text("JNI-Call: ToReflectedField"); */
898
899         return NULL;
900 }
901
902
903 /***************** throw java.lang.Throwable object  ******************************/
904
905 jint Throw(JNIEnv* env, jthrowable obj)
906 {
907         *exceptionptr = (java_objectheader*) obj;
908
909         return 0;
910 }
911
912
913 /*******************************************************************************
914
915         create exception object from the class clazz with the 
916         specified message and cause it to be thrown
917
918 *******************************************************************************/
919
920 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
921 {
922         java_lang_Throwable *o;
923
924         /* instantiate exception object */
925         o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
926
927         if (!o) return (-1);
928
929         o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
930
931         *exceptionptr = (java_objectheader *) o;
932
933         return 0;
934 }
935
936
937 /************************* check if exception occured *****************************/
938
939 jthrowable ExceptionOccurred (JNIEnv* env) 
940 {
941         return (jthrowable) *exceptionptr;
942 }
943
944 /********** print exception and a backtrace of the stack (for debugging) **********/
945
946 void ExceptionDescribe (JNIEnv* env) 
947 {
948         utf_display((*exceptionptr)->vftbl->class->name);
949         printf ("\n");
950         fflush (stdout);        
951 }
952
953
954 /******************* clear any exception currently being thrown *******************/
955
956 void ExceptionClear (JNIEnv* env) 
957 {
958         *exceptionptr = NULL;   
959 }
960
961
962 /********** raises a fatal error and does not expect the VM to recover ************/
963
964 void FatalError (JNIEnv* env, const char *msg)
965 {
966         panic((char *) msg);    
967 }
968
969 /******************* creates a new local reference frame **************************/ 
970
971 jint PushLocalFrame(JNIEnv* env, jint capacity)
972 {
973         /* empty */
974
975         return 0;
976 }
977
978 /**************** Pops off the current local reference frame **********************/
979
980 jobject PopLocalFrame(JNIEnv* env, jobject result)
981 {
982         /* empty */
983
984         return NULL;
985 }
986     
987
988 /** Creates a new global reference to the object referred to by the obj argument **/
989     
990 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
991 {
992         return lobj;
993 }
994
995 /*************  Deletes the global reference pointed to by globalRef **************/
996
997 void DeleteGlobalRef (JNIEnv* env, jobject gref)
998 {
999         /* empty */
1000 }
1001
1002
1003 /*************** Deletes the local reference pointed to by localRef ***************/
1004
1005 void DeleteLocalRef (JNIEnv* env, jobject localRef)
1006 {
1007         /* empty */
1008 }
1009
1010 /********** Tests whether two references refer to the same Java object ************/
1011
1012 jboolean IsSameObject (JNIEnv* env, jobject obj1, jobject obj2)
1013 {
1014         return (obj1==obj2);
1015 }
1016
1017 /***** Creates a new local reference that refers to the same object as ref  *******/
1018
1019 jobject NewLocalRef (JNIEnv* env, jobject ref)
1020 {
1021         return ref;
1022 }
1023
1024 /*********************************************************************************** 
1025
1026         Ensures that at least a given number of local references can 
1027         be created in the current thread
1028
1029  **********************************************************************************/   
1030
1031 jint EnsureLocalCapacity (JNIEnv* env, jint capacity)
1032 {
1033         return 0; /* return 0 on success */
1034 }
1035
1036
1037 /********* Allocates a new Java object without invoking a constructor *************/
1038
1039 jobject AllocObject (JNIEnv* env, jclass clazz)
1040 {
1041         java_objectheader *o = builtin_new(clazz);      
1042         return o;
1043 }
1044
1045
1046 /*********************************************************************************** 
1047
1048         Constructs a new Java object
1049         arguments that are to be passed to the constructor are placed after methodID
1050
1051 ***********************************************************************************/
1052
1053 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
1054 {
1055         java_objectheader *o;
1056         void* args[3];
1057         int argcount=get_parametercount(methodID);
1058         int i;
1059         va_list vaargs;
1060
1061         /* log_text("JNI-Call: NewObject"); */
1062
1063         if (argcount > 3) {
1064                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1065                 log_text("Too many arguments. NewObject does not support that");
1066                 return 0;
1067         }
1068
1069         
1070         o = builtin_new (clazz);         /*          create object */
1071         
1072         if (!o) return NULL;
1073
1074         va_start(vaargs,methodID);
1075         for (i=0;i<argcount;i++) {
1076                 args[i]=va_arg(vaargs,void*);
1077         }
1078         va_end(vaargs);
1079         asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
1080
1081         return o;
1082 }
1083
1084
1085 /*********************************************************************************** 
1086
1087        Constructs a new Java object
1088        arguments that are to be passed to the constructor are placed in va_list args 
1089
1090 ***********************************************************************************/
1091
1092 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1093 {
1094         /* log_text("JNI-Call: NewObjectV"); */
1095
1096         return NULL;
1097 }
1098
1099
1100 /*********************************************************************************** 
1101
1102         Constructs a new Java object
1103         arguments that are to be passed to the constructor are placed in 
1104         args array of jvalues 
1105
1106 ***********************************************************************************/
1107
1108 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1109 {
1110         /* log_text("JNI-Call: NewObjectA"); */
1111
1112         return NULL;
1113 }
1114
1115
1116 /************************ returns the class of an object **************************/ 
1117
1118 jclass GetObjectClass(JNIEnv* env, jobject obj)
1119 {
1120         classinfo *c = obj->vftbl->class;
1121
1122         use_class_as_object(c);
1123
1124         return c;
1125 }
1126
1127
1128 /************* tests whether an object is an instance of a class ******************/
1129
1130 jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1131 {
1132         return builtin_instanceof(obj,clazz);
1133 }
1134
1135
1136 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1137  
1138 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1139 {
1140         log_text("JNI-Call: FromReflectedField");
1141
1142         return 0;
1143 }
1144
1145
1146 /**********************************************************************************
1147
1148         converts a method ID to a java.lang.reflect.Method or 
1149         java.lang.reflect.Constructor object
1150
1151 **********************************************************************************/
1152
1153 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1154 {
1155         log_text("JNI-Call: ToReflectedMethod");
1156
1157         return NULL;
1158 }
1159
1160
1161 /**************** returns the method ID for an instance method ********************/
1162
1163 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1164 {
1165         jmethodID m;
1166
1167         m = class_resolvemethod (
1168                 clazz, 
1169                 utf_new_char ((char*) name), 
1170                 utf_new_char ((char*) sig)
1171         );
1172
1173         if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1174         else if (m->flags & ACC_STATIC)   {
1175                 m=0;
1176                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1177         }
1178         return m;
1179 }
1180
1181
1182 /******************** JNI-functions for calling instance methods ******************/
1183
1184 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1185 {
1186         jobject ret;
1187         va_list vaargs;
1188
1189 /*      log_text("JNI-Call: CallObjectMethod");*/
1190
1191         va_start(vaargs, methodID);
1192         ret = callObjectMethod(obj, methodID, vaargs);
1193         va_end(vaargs);
1194
1195         return ret;
1196 }
1197
1198
1199 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1200 {
1201         return callObjectMethod(obj,methodID,args);
1202 }
1203
1204
1205 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1206 {
1207         log_text("JNI-Call: CallObjectMethodA");
1208
1209         return NULL;
1210 }
1211
1212
1213
1214
1215 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1216 {
1217         jboolean ret;
1218         va_list vaargs;
1219
1220 /*      log_text("JNI-Call: CallBooleanMethod");*/
1221
1222         va_start(vaargs,methodID);
1223         ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
1224         va_end(vaargs);
1225         return ret;
1226
1227 }
1228
1229 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1230 {
1231         return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
1232
1233 }
1234
1235 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1236 {
1237         log_text("JNI-Call: CallBooleanMethodA");
1238
1239         return 0;
1240 }
1241
1242 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1243 {
1244         jbyte ret;
1245         va_list vaargs;
1246
1247 /*      log_text("JNI-Call: CallVyteMethod");*/
1248
1249         va_start(vaargs,methodID);
1250         ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
1251         va_end(vaargs);
1252         return ret;
1253
1254 }
1255
1256 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1257 {
1258 /*      log_text("JNI-Call: CallByteMethodV");*/
1259         return callIntegerMethod(obj,methodID,'B',args);
1260 }
1261
1262
1263 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1264 {
1265         log_text("JNI-Call: CallByteMethodA");
1266
1267         return 0;
1268 }
1269
1270
1271 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1272 {
1273         jchar ret;
1274         va_list vaargs;
1275
1276 /*      log_text("JNI-Call: CallCharMethod");*/
1277
1278         va_start(vaargs,methodID);
1279         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
1280         va_end(vaargs);
1281
1282         return ret;
1283 }
1284
1285
1286 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1287 {
1288 /*      log_text("JNI-Call: CallCharMethodV");*/
1289         return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
1290 }
1291
1292
1293 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1294 {
1295         log_text("JNI-Call: CallCharMethodA");
1296
1297         return 0;
1298 }
1299
1300
1301 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1302 {
1303         jshort ret;
1304         va_list vaargs;
1305
1306 /*      log_text("JNI-Call: CallShortMethod");*/
1307
1308         va_start(vaargs, methodID);
1309         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
1310         va_end(vaargs);
1311
1312         return ret;
1313 }
1314
1315
1316 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1317 {
1318         return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
1319 }
1320
1321
1322 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1323 {
1324         log_text("JNI-Call: CallShortMethodA");
1325
1326         return 0;
1327 }
1328
1329
1330
1331 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1332 {
1333         jint ret;
1334         va_list vaargs;
1335
1336         va_start(vaargs,methodID);
1337         ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
1338         va_end(vaargs);
1339
1340         return ret;
1341 }
1342
1343
1344 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1345 {
1346         return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
1347 }
1348
1349
1350 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1351 {
1352         log_text("JNI-Call: CallIntMethodA");
1353
1354         return 0;
1355 }
1356
1357
1358
1359 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1360 {
1361         log_text("JNI-Call: CallLongMethod");
1362
1363         return 0;
1364 }
1365
1366
1367 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1368 {
1369         log_text("JNI-Call: CallLongMethodV");
1370
1371         return 0;
1372 }
1373
1374
1375 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1376 {
1377         log_text("JNI-Call: CallLongMethodA");
1378
1379         return 0;
1380 }
1381
1382
1383
1384 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1385 {
1386         jfloat ret;
1387         va_list vaargs;
1388
1389 /*      log_text("JNI-Call: CallFloatMethod");*/
1390
1391         va_start(vaargs,methodID);
1392         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
1393         va_end(vaargs);
1394
1395         return ret;
1396 }
1397
1398
1399 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1400 {
1401         log_text("JNI-Call: CallFloatMethodV");
1402         return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
1403 }
1404
1405
1406 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1407 {
1408         log_text("JNI-Call: CallFloatMethodA");
1409
1410         return 0;
1411 }
1412
1413
1414
1415 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1416 {
1417         jdouble ret;
1418         va_list vaargs;
1419
1420 /*      log_text("JNI-Call: CallDoubleMethod");*/
1421
1422         va_start(vaargs,methodID);
1423         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
1424         va_end(vaargs);
1425
1426         return ret;
1427 }
1428
1429
1430 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1431 {
1432         log_text("JNI-Call: CallDoubleMethodV");
1433         return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
1434 }
1435
1436
1437 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1438 {
1439         log_text("JNI-Call: CallDoubleMethodA");
1440         return 0;
1441 }
1442
1443
1444
1445 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1446 {
1447         va_list vaargs;
1448
1449 /*      log_text("JNI-Call: CallVoidMethod");*/
1450
1451         va_start(vaargs,methodID);
1452         (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
1453         va_end(vaargs);
1454 }
1455
1456
1457 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1458 {
1459         log_text("JNI-Call: CallVoidMethodV");
1460         (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
1461 }
1462
1463
1464 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1465 {
1466         log_text("JNI-Call: CallVoidMethodA");
1467 }
1468
1469
1470
1471 jobject CallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1472 {
1473         log_text("JNI-Call: CallNonvirtualObjectMethod");
1474
1475         return NULL;
1476 }
1477
1478
1479 jobject CallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1480 {
1481         log_text("JNI-Call: CallNonvirtualObjectMethodV");
1482
1483         return NULL;
1484 }
1485
1486
1487 jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1488 {
1489         log_text("JNI-Call: CallNonvirtualObjectMethodA");
1490
1491         return NULL;
1492 }
1493
1494
1495
1496 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1497 {
1498         jboolean ret;
1499         va_list vaargs;
1500
1501 /*      log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1502
1503         va_start(vaargs,methodID);
1504         ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
1505         va_end(vaargs);
1506         return ret;
1507
1508 }
1509
1510
1511 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1512 {
1513 /*      log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1514         return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
1515 }
1516
1517
1518 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1519 {
1520         log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1521
1522         return 0;
1523 }
1524
1525
1526
1527 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1528 {
1529         jbyte ret;
1530         va_list vaargs;
1531
1532 /*      log_text("JNI-Call: CallNonvirutalByteMethod");*/
1533
1534         va_start(vaargs,methodID);
1535         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
1536         va_end(vaargs);
1537         return ret;
1538 }
1539
1540
1541 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1542 {
1543         /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1544         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
1545
1546 }
1547
1548
1549 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1550 {
1551         log_text("JNI-Call: CallNonvirtualByteMethodA");
1552
1553         return 0;
1554 }
1555
1556
1557
1558 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1559 {
1560         jchar ret;
1561         va_list vaargs;
1562
1563 /*      log_text("JNI-Call: CallNonVirtualCharMethod");*/
1564
1565         va_start(vaargs,methodID);
1566         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
1567         va_end(vaargs);
1568         return ret;
1569 }
1570
1571
1572 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1573 {
1574         /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1575         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
1576 }
1577
1578
1579 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1580 {
1581         log_text("JNI-Call: CallNonvirtualCharMethodA");
1582
1583         return 0;
1584 }
1585
1586
1587
1588 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1589 {
1590         jshort ret;
1591         va_list vaargs;
1592
1593         /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1594
1595         va_start(vaargs,methodID);
1596         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
1597         va_end(vaargs);
1598         return ret;
1599 }
1600
1601
1602 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1603 {
1604         /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1605         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
1606 }
1607
1608
1609 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1610 {
1611         log_text("JNI-Call: CallNonvirtualShortMethodA");
1612
1613         return 0;
1614 }
1615
1616
1617
1618 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1619 {
1620
1621         jint ret;
1622         va_list vaargs;
1623
1624         /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1625
1626         va_start(vaargs,methodID);
1627         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
1628         va_end(vaargs);
1629         return ret;
1630 }
1631
1632
1633 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1634 {
1635         /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1636         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
1637 }
1638
1639
1640 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1641 {
1642         log_text("JNI-Call: CallNonvirtualIntMethodA");
1643
1644         return 0;
1645 }
1646
1647
1648
1649 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1650 {
1651         log_text("JNI-Call: CallNonvirtualLongMethod");
1652
1653         return 0;
1654 }
1655
1656
1657 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1658 {
1659         log_text("JNI-Call: CallNonvirtualLongMethodV");
1660
1661         return 0;
1662 }
1663
1664
1665 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1666 {
1667         log_text("JNI-Call: CallNonvirtualLongMethodA");
1668
1669         return 0;
1670 }
1671
1672
1673
1674 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1675 {
1676         jfloat ret;
1677         va_list vaargs;
1678
1679         /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1680
1681
1682         va_start(vaargs,methodID);
1683         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
1684         va_end(vaargs);
1685         return ret;
1686
1687 }
1688
1689
1690 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1691 {
1692         log_text("JNI-Call: CallNonvirtualFloatMethodV");
1693         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
1694 }
1695
1696
1697 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1698 {
1699         log_text("JNI-Call: CallNonvirtualFloatMethodA");
1700
1701         return 0;
1702 }
1703
1704
1705
1706 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1707 {
1708         jdouble ret;
1709         va_list vaargs;
1710         log_text("JNI-Call: CallNonvirtualDoubleMethod");
1711
1712         va_start(vaargs,methodID);
1713         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
1714         va_end(vaargs);
1715         return ret;
1716
1717 }
1718
1719
1720 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1721 {
1722 /*      log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
1723         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
1724 }
1725
1726
1727 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1728 {
1729         log_text("JNI-Call: CallNonvirtualDoubleMethodA");
1730
1731         return 0;
1732 }
1733
1734
1735
1736 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1737 {
1738         va_list vaargs;
1739
1740 /*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
1741
1742         va_start(vaargs,methodID);
1743         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
1744         va_end(vaargs);
1745
1746 }
1747
1748
1749 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1750 {
1751 /*      log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
1752
1753         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
1754
1755 }
1756
1757
1758 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1759 {
1760         log_text("JNI-Call: CallNonvirtualVoidMethodA");
1761 }
1762
1763 /************************* JNI-functions for accessing fields ************************/
1764
1765 jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
1766 {
1767         jfieldID f;
1768
1769 /*      log_text("========================= searching for:");
1770         log_text(name);
1771         log_text(sig);*/
1772         f = jclass_findfield(clazz,
1773                             utf_new_char ((char*) name), 
1774                             utf_new_char ((char*) sig)
1775                             ); 
1776         
1777         if (!f) { 
1778 /*              utf_display(clazz->name);
1779                 log_text(name);
1780                 log_text(sig);*/
1781                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
1782         }
1783         return f;
1784 }
1785
1786 /*************************** retrieve fieldid, abort on error ************************/
1787
1788 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
1789 {
1790     jfieldID id = GetFieldID(env, clazz, name, sig);
1791
1792     if (!id) {
1793        log_text("class:");
1794        utf_display(clazz->name);
1795        log_text("\nfield:");
1796        log_text(name);
1797        log_text("sig:");
1798        log_text(sig);
1799
1800        panic("setfield_critical failed"); 
1801     }
1802     return id;
1803 }
1804
1805 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
1806 {
1807         return getField(obj,jobject,fieldID);
1808 }
1809
1810 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
1811 {
1812         return getField(obj,jboolean,fieldID);
1813 }
1814
1815
1816 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
1817 {
1818         return getField(obj,jbyte,fieldID);
1819 }
1820
1821
1822 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
1823 {
1824         return getField(obj,jchar,fieldID);
1825 }
1826
1827
1828 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
1829 {
1830         return getField(obj,jshort,fieldID);
1831 }
1832
1833
1834 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
1835 {
1836         return getField(obj,jint,fieldID);
1837 }
1838
1839
1840 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
1841 {
1842         return getField(obj,jlong,fieldID);
1843 }
1844
1845
1846 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
1847 {
1848         return getField(obj,jfloat,fieldID);
1849 }
1850
1851
1852 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
1853 {
1854         return getField(obj,jdouble,fieldID);
1855 }
1856
1857 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
1858 {
1859         setField(obj,jobject,fieldID,val);
1860 }
1861
1862
1863 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
1864 {
1865         setField(obj,jboolean,fieldID,val);
1866 }
1867
1868
1869 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
1870 {
1871         setField(obj,jbyte,fieldID,val);
1872 }
1873
1874
1875 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
1876 {
1877         setField(obj,jchar,fieldID,val);
1878 }
1879
1880
1881 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
1882 {
1883         setField(obj,jshort,fieldID,val);
1884 }
1885
1886
1887 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
1888 {
1889         setField(obj,jint,fieldID,val);
1890 }
1891
1892
1893 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
1894 {
1895         setField(obj,jlong,fieldID,val);
1896 }
1897
1898
1899 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
1900 {
1901         setField(obj,jfloat,fieldID,val);
1902 }
1903
1904
1905 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
1906 {
1907         setField(obj,jdouble,fieldID,val);
1908 }
1909
1910
1911 /**************** JNI-functions for calling static methods **********************/ 
1912
1913 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
1914 {
1915         jmethodID m;
1916
1917         m = class_resolvemethod(clazz,
1918                                                         utf_new_char((char *) name),
1919                                                         utf_new_char((char *) sig));
1920
1921         if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1922         else if (!(m->flags & ACC_STATIC))   {
1923                 m=0;
1924                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
1925         }
1926
1927         return m;
1928 }
1929
1930
1931 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1932 {
1933         jobject ret;
1934         va_list vaargs;
1935
1936         /* log_text("JNI-Call: CallStaticObjectMethod");*/
1937
1938         va_start(vaargs, methodID);
1939         ret = callObjectMethod(0, methodID, vaargs);
1940         va_end(vaargs);
1941
1942         return ret;
1943 }
1944
1945
1946 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1947 {
1948         /* log_text("JNI-Call: CallStaticObjectMethodV"); */
1949         
1950         return callObjectMethod(0,methodID,args);
1951 }
1952
1953
1954 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1955 {
1956         log_text("JNI-Call: CallStaticObjectMethodA");
1957
1958         return NULL;
1959 }
1960
1961
1962 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1963 {
1964         jboolean ret;
1965         va_list vaargs;
1966
1967         va_start(vaargs, methodID);
1968         ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
1969         va_end(vaargs);
1970
1971         return ret;
1972 }
1973
1974
1975 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
1976 {
1977         return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
1978 }
1979
1980
1981 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
1982 {
1983         log_text("JNI-Call: CallStaticBooleanMethodA");
1984
1985         return 0;
1986 }
1987
1988
1989 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1990 {
1991         jbyte ret;
1992         va_list vaargs;
1993
1994         /*      log_text("JNI-Call: CallStaticByteMethod");*/
1995
1996         va_start(vaargs, methodID);
1997         ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
1998         va_end(vaargs);
1999
2000         return ret;
2001 }
2002
2003
2004 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2005 {
2006         return (jbyte) callIntegerMethod(0, methodID, 'B', args);
2007 }
2008
2009
2010 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2011 {
2012         log_text("JNI-Call: CallStaticByteMethodA");
2013
2014         return 0;
2015 }
2016
2017
2018 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2019 {
2020         jchar ret;
2021         va_list vaargs;
2022
2023         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2024
2025         va_start(vaargs, methodID);
2026         ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
2027         va_end(vaargs);
2028
2029         return ret;
2030 }
2031
2032
2033 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2034 {
2035         return (jchar) callIntegerMethod(0, methodID, 'C', args);
2036 }
2037
2038
2039 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2040 {
2041         log_text("JNI-Call: CallStaticCharMethodA");
2042
2043         return 0;
2044 }
2045
2046
2047
2048 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2049 {
2050         jshort ret;
2051         va_list vaargs;
2052
2053         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2054
2055         va_start(vaargs, methodID);
2056         ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
2057         va_end(vaargs);
2058
2059         return ret;
2060 }
2061
2062
2063 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2064 {
2065         /*log_text("JNI-Call: CallStaticShortMethodV");*/
2066         return (jshort) callIntegerMethod(0, methodID, 'S', args);
2067 }
2068
2069
2070 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2071 {
2072         log_text("JNI-Call: CallStaticShortMethodA");
2073
2074         return 0;
2075 }
2076
2077
2078
2079 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2080 {
2081         jint ret;
2082         va_list vaargs;
2083
2084         /*      log_text("JNI-Call: CallStaticIntMethod");*/
2085
2086         va_start(vaargs, methodID);
2087         ret = callIntegerMethod(0, methodID, 'I', vaargs);
2088         va_end(vaargs);
2089
2090         return ret;
2091 }
2092
2093
2094 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2095 {
2096         log_text("JNI-Call: CallStaticIntMethodV");
2097
2098         return callIntegerMethod(0, methodID, 'I', args);
2099 }
2100
2101
2102 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2103 {
2104         log_text("JNI-Call: CallStaticIntMethodA");
2105
2106         return 0;
2107 }
2108
2109
2110
2111 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2112 {
2113         jlong ret;
2114         va_list vaargs;
2115
2116         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2117
2118         va_start(vaargs, methodID);
2119         ret = callLongMethod(0, methodID, vaargs);
2120         va_end(vaargs);
2121
2122         return ret;
2123 }
2124
2125
2126 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2127 {
2128         log_text("JNI-Call: CallStaticLongMethodV");
2129         
2130         return callLongMethod(0,methodID,args);
2131 }
2132
2133
2134 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2135 {
2136         log_text("JNI-Call: CallStaticLongMethodA");
2137
2138         return 0;
2139 }
2140
2141
2142
2143 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2144 {
2145         jfloat ret;
2146         va_list vaargs;
2147
2148         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2149
2150         va_start(vaargs, methodID);
2151         ret = callFloatMethod(0, methodID, vaargs, 'F');
2152         va_end(vaargs);
2153
2154         return ret;
2155 }
2156
2157
2158 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2159 {
2160
2161         return callFloatMethod(0, methodID, args, 'F');
2162
2163 }
2164
2165
2166 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2167 {
2168         log_text("JNI-Call: CallStaticFloatMethodA");
2169
2170         return 0;
2171 }
2172
2173
2174
2175 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2176 {
2177         jdouble ret;
2178         va_list vaargs;
2179
2180         /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
2181
2182         va_start(vaargs,methodID);
2183         ret = callFloatMethod(0, methodID, vaargs, 'D');
2184         va_end(vaargs);
2185
2186         return ret;
2187 }
2188
2189
2190 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2191 {
2192         log_text("JNI-Call: CallStaticDoubleMethodV");
2193
2194         return callFloatMethod(0, methodID, args, 'D');
2195 }
2196
2197
2198 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2199 {
2200         log_text("JNI-Call: CallStaticDoubleMethodA");
2201
2202         return 0;
2203 }
2204
2205
2206 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2207 {
2208         va_list vaargs;
2209
2210 /*      log_text("JNI-Call: CallStaticVoidMethod");*/
2211
2212         va_start(vaargs, methodID);
2213         (void) callIntegerMethod(0, methodID, 'V', vaargs);
2214         va_end(vaargs);
2215 }
2216
2217
2218 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2219 {
2220         log_text("JNI-Call: CallStaticVoidMethodV");
2221         (void)callIntegerMethod(0, methodID, 'V', args);
2222 }
2223
2224
2225 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2226 {
2227         log_text("JNI-Call: CallStaticVoidMethodA");
2228 }
2229
2230
2231 /****************** JNI-functions for accessing static fields ********************/
2232
2233 jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
2234 {
2235         jfieldID f;
2236
2237         f = jclass_findfield(clazz,
2238                             utf_new_char ((char*) name), 
2239                             utf_new_char ((char*) sig)
2240                             ); 
2241         
2242         if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2243
2244         return f;
2245 }
2246
2247
2248 jobject GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2249 {
2250         class_init(clazz);
2251         return fieldID->value.a;       
2252 }
2253
2254
2255 jboolean GetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2256 {
2257         class_init(clazz);
2258         return fieldID->value.i;       
2259 }
2260
2261
2262 jbyte GetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2263 {
2264         class_init(clazz);
2265         return fieldID->value.i;       
2266 }
2267
2268
2269 jchar GetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2270 {
2271         class_init(clazz);
2272         return fieldID->value.i;       
2273 }
2274
2275
2276 jshort GetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2277 {
2278         class_init(clazz);
2279         return fieldID->value.i;       
2280 }
2281
2282
2283 jint GetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2284 {
2285         class_init(clazz);
2286         return fieldID->value.i;       
2287 }
2288
2289
2290 jlong GetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2291 {
2292         class_init(clazz);
2293         return fieldID->value.l;
2294 }
2295
2296
2297 jfloat GetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2298 {
2299         class_init(clazz);
2300         return fieldID->value.f;
2301 }
2302
2303
2304 jdouble GetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID)
2305 {
2306         class_init(clazz);
2307         return fieldID->value.d;
2308 }
2309
2310
2311
2312 void SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2313 {
2314         class_init(clazz);
2315         fieldID->value.a = value;
2316 }
2317
2318
2319 void SetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2320 {
2321         class_init(clazz);
2322         fieldID->value.i = value;
2323 }
2324
2325
2326 void SetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2327 {
2328         class_init(clazz);
2329         fieldID->value.i = value;
2330 }
2331
2332
2333 void SetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2334 {
2335         class_init(clazz);
2336         fieldID->value.i = value;
2337 }
2338
2339
2340 void SetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2341 {
2342         class_init(clazz);
2343         fieldID->value.i = value;
2344 }
2345
2346
2347 void SetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2348 {
2349         class_init(clazz);
2350         fieldID->value.i = value;
2351 }
2352
2353
2354 void SetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2355 {
2356         class_init(clazz);
2357         fieldID->value.l = value;
2358 }
2359
2360
2361 void SetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2362 {
2363         class_init(clazz);
2364         fieldID->value.f = value;
2365 }
2366
2367
2368 void SetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2369 {
2370         class_init(clazz);
2371         fieldID->value.d = value;
2372 }
2373
2374
2375 /*****  create new java.lang.String object from an array of Unicode characters ****/ 
2376
2377 jstring NewString (JNIEnv *env, const jchar *buf, jsize len)
2378 {
2379         u4 i;
2380         java_lang_String *s;
2381         java_chararray *a;
2382         
2383         s = (java_lang_String*) builtin_new (class_java_lang_String);
2384         a = builtin_newarray_char (len);
2385
2386         /* javastring or characterarray could not be created */
2387         if ( (!a) || (!s) ) return NULL;
2388
2389         /* copy text */
2390         for (i=0; i<len; i++) a->data[i] = buf[i];
2391         s -> value = a;
2392         s -> offset = 0;
2393         s -> count = len;
2394
2395         return (jstring) s;
2396 }
2397
2398
2399 static char emptyString[]="";
2400 static jchar emptyStringJ[]={0,0};
2401
2402 /******************* returns the length of a Java string ***************************/
2403
2404 jsize GetStringLength (JNIEnv *env, jstring str)
2405 {
2406         return ((java_lang_String*) str)->count;
2407 }
2408
2409
2410 /********************  convertes javastring to u2-array ****************************/
2411         
2412 u2 *javastring_tou2 (jstring so) 
2413 {
2414         java_lang_String *s = (java_lang_String*) so;
2415         java_chararray *a;
2416         u4 i;
2417         u2 *stringbuffer;
2418         
2419         if (!s) return NULL;
2420
2421         a = s->value;
2422         if (!a) return NULL;
2423
2424         /* allocate memory */
2425         stringbuffer = MNEW( u2 , s->count + 1 );
2426
2427         /* copy text */
2428         for (i=0; i<s->count; i++) stringbuffer[i] = a->data[s->offset+i];
2429         
2430         /* terminate string */
2431         stringbuffer[i] = '\0';
2432
2433         return stringbuffer;
2434 }
2435
2436 /********* returns a pointer to an array of Unicode characters of the string *******/
2437
2438 const jchar *GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy)
2439 {       
2440         jchar *jc=javastring_tou2(str);
2441
2442         if (jc) {
2443                 if (isCopy) *isCopy=JNI_TRUE;
2444                 return jc;
2445         }
2446         if (isCopy) *isCopy=JNI_TRUE;
2447         return emptyStringJ;
2448 }
2449
2450 /**************** native code no longer needs access to chars **********************/
2451
2452 void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
2453 {
2454         if (chars==emptyStringJ) return;
2455         MFREE(((jchar*) chars),jchar,((java_lang_String*) str)->count+1);
2456 }
2457
2458 /************ create new java.lang.String object from utf8-characterarray **********/
2459
2460 jstring NewStringUTF (JNIEnv *env, const char *utf)
2461 {
2462 /*    log_text("NewStringUTF called");*/
2463     return (jstring) javastring_new(utf_new_char((char *) utf));
2464 }
2465
2466 /****************** returns the utf8 length in bytes of a string *******************/
2467
2468 jsize GetStringUTFLength (JNIEnv *env, jstring string)
2469 {   
2470     java_lang_String *s = (java_lang_String*) string;
2471
2472     return (jsize) u2_utflength(s->value->data, s->count); 
2473 }
2474
2475
2476 /************ converts a Javastring to an array of UTF-8 characters ****************/
2477
2478 const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
2479 {
2480     utf *u;
2481
2482     u = javastring_toutf((java_lang_String *) string, false);
2483
2484     if (isCopy)
2485                 *isCopy = JNI_FALSE;
2486         
2487     if (u)
2488                 return u->text;
2489
2490     return emptyString;
2491         
2492 }
2493
2494
2495 /***************** native code no longer needs access to utf ***********************/
2496
2497 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
2498 {
2499     /*we don't release utf chars right now, perhaps that should be done later. Since there is always one reference
2500         the garbage collector will never get them*/
2501         /*
2502     log_text("JNI-Call: ReleaseStringUTFChars");
2503     utf_display(utf_new_char(chars));
2504         */
2505 }
2506
2507 /************************** array operations ***************************************/
2508
2509 jsize GetArrayLength(JNIEnv *env, jarray array)
2510 {
2511     return array->size;
2512 }
2513
2514
2515 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
2516 {
2517         java_objectarray *j;
2518
2519     if (len < 0) {
2520                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2521                 return NULL;
2522     }
2523
2524     j = builtin_anewarray(len, clazz);
2525
2526     return j;
2527 }
2528
2529
2530 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
2531 {
2532     jobject j = NULL;
2533
2534     if (index < array->header.size)     
2535                 j = array->data[index];
2536     else
2537                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2538     
2539     return j;
2540 }
2541
2542
2543 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
2544 {
2545     if (index >= array->header.size)
2546                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2547
2548     else {
2549                 /* check if the class of value is a subclass of the element class of the array */
2550                 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
2551                         *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
2552
2553                 else
2554                         array->data[index] = val;
2555     }
2556 }
2557
2558
2559
2560 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
2561 {
2562         java_booleanarray *j;
2563
2564     if (len < 0) {
2565                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2566                 return NULL;
2567     }
2568
2569     j = builtin_newarray_boolean(len);
2570
2571     return j;
2572 }
2573
2574
2575 jbyteArray NewByteArray(JNIEnv *env, jsize len)
2576 {
2577         java_bytearray *j;
2578
2579     if (len < 0) {
2580                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2581                 return NULL;
2582     }
2583
2584     j = builtin_newarray_byte(len);
2585
2586     return j;
2587 }
2588
2589
2590 jcharArray NewCharArray(JNIEnv *env, jsize len)
2591 {
2592         java_chararray *j;
2593
2594     if (len < 0) {
2595                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2596                 return NULL;
2597     }
2598
2599     j = builtin_newarray_char(len);
2600
2601     return j;
2602 }
2603
2604
2605 jshortArray NewShortArray(JNIEnv *env, jsize len)
2606 {
2607         java_shortarray *j;
2608
2609     if (len < 0) {
2610                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2611                 return NULL;
2612     }
2613
2614     j = builtin_newarray_short(len);
2615
2616     return j;
2617 }
2618
2619
2620 jintArray NewIntArray(JNIEnv *env, jsize len)
2621 {
2622         java_intarray *j;
2623
2624     if (len < 0) {
2625                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2626                 return NULL;
2627     }
2628
2629     j = builtin_newarray_int(len);
2630
2631     return j;
2632 }
2633
2634
2635 jlongArray NewLongArray(JNIEnv *env, jsize len)
2636 {
2637         java_longarray *j;
2638
2639     if (len < 0) {
2640                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2641                 return NULL;
2642     }
2643
2644     j = builtin_newarray_long(len);
2645
2646     return j;
2647 }
2648
2649
2650 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
2651 {
2652         java_floatarray *j;
2653
2654     if (len < 0) {
2655                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2656                 return NULL;
2657     }
2658
2659     j = builtin_newarray_float(len);
2660
2661     return j;
2662 }
2663
2664
2665 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
2666 {
2667         java_doublearray *j;
2668
2669     if (len < 0) {
2670                 *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
2671                 return NULL;
2672     }
2673
2674     j = builtin_newarray_double(len);
2675
2676     return j;
2677 }
2678
2679
2680 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2681 {
2682     if (isCopy) *isCopy = JNI_FALSE;
2683     return array->data;
2684 }
2685
2686
2687 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2688 {
2689     if (isCopy) *isCopy = JNI_FALSE;
2690     return array->data;
2691 }
2692
2693
2694 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2695 {
2696     if (isCopy) *isCopy = JNI_FALSE;
2697     return array->data;
2698 }
2699
2700
2701 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2702 {
2703     if (isCopy) *isCopy = JNI_FALSE;
2704     return array->data;
2705 }
2706
2707
2708 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2709 {
2710     if (isCopy) *isCopy = JNI_FALSE;
2711     return array->data;
2712 }
2713
2714
2715 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2716 {
2717     if (isCopy) *isCopy = JNI_FALSE;
2718     return array->data;
2719 }
2720
2721
2722 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2723 {
2724     if (isCopy) *isCopy = JNI_FALSE;
2725     return array->data;
2726 }
2727
2728
2729 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2730 {
2731     if (isCopy) *isCopy = JNI_FALSE;
2732     return array->data;
2733 }
2734
2735
2736
2737 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2738 {
2739     /* empty */
2740 }
2741
2742
2743 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2744 {
2745     /* empty */
2746 }
2747
2748
2749 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2750 {
2751     /* empty */
2752 }
2753
2754
2755 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2756 {
2757     /* empty */
2758 }
2759
2760
2761 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2762 {
2763     /* empty */
2764 }
2765
2766
2767 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2768 {
2769     /* empty */
2770 }
2771
2772
2773 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2774 {
2775     /* empty */
2776 }
2777
2778
2779 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2780 {
2781     /* empty */
2782 }
2783
2784
2785 void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2786 {
2787     if (start < 0 || len < 0 || start + len > array->header.size)
2788                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2789
2790     else
2791                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2792 }
2793
2794
2795 void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2796 {
2797     if (start < 0 || len < 0 || start + len > array->header.size) 
2798                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2799
2800     else
2801                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2802 }
2803
2804
2805 void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
2806 {
2807     if (start < 0 || len < 0 || start + len > array->header.size)
2808                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2809
2810     else
2811                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2812 }
2813
2814
2815 void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2816 {
2817     if (start < 0 || len < 0 || start + len > array->header.size)
2818                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2819
2820     else        
2821                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2822 }
2823
2824
2825 void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
2826 {
2827     if (start < 0 || len < 0 || start + len > array->header.size)
2828                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2829
2830     else
2831                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2832 }
2833
2834
2835 void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
2836 {
2837     if (start < 0 || len < 0 || start + len > array->header.size)
2838                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2839
2840     else
2841                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2842 }
2843
2844
2845 void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
2846 {
2847     if (start < 0 || len < 0 || start + len > array->header.size)
2848                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2849
2850     else
2851                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2852 }
2853
2854
2855 void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2856 {
2857     if (start < 0 || len < 0 || start+len>array->header.size)
2858                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2859
2860     else
2861                 memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
2862 }
2863
2864
2865 void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2866 {
2867     if (start < 0 || len < 0 || start + len > array->header.size)
2868                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2869
2870     else
2871                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2872 }
2873
2874
2875 void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
2876 {
2877     if (start < 0 || len < 0 || start + len > array->header.size)
2878                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2879
2880     else
2881                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2882 }
2883
2884
2885 void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *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
2896 void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2897 {
2898     if (start < 0 || len < 0 || start + len > array->header.size)
2899                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2900
2901     else
2902                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2903 }
2904
2905
2906 void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *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 SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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
2939 void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
2940 {
2941     if (start < 0 || len < 0 || start + len > array->header.size)
2942                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
2943
2944     else
2945                 memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
2946 }
2947
2948
2949 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2950 {
2951     log_text("JNI-Call: RegisterNatives");
2952     return 0;
2953 }
2954
2955
2956 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2957 {
2958     log_text("JNI-Call: UnregisterNatives");
2959     return 0;
2960 }
2961
2962 /******************************* monitor operations ********************************/
2963
2964 jint MonitorEnter (JNIEnv* env, jobject obj)
2965 {
2966     builtin_monitorenter(obj);
2967     return 0;
2968 }
2969
2970
2971 jint MonitorExit (JNIEnv* env, jobject obj)
2972 {
2973     builtin_monitorexit(obj);
2974     return 0;
2975 }
2976
2977
2978 /************************************* JavaVM interface ****************************/
2979 #ifdef __cplusplus
2980 #error CPP mode not supported yet
2981 #else
2982 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
2983 {
2984     log_text("JNI-Call: GetJavaVM");
2985     *vm=&javaVM;
2986     return 0;
2987 }
2988 #endif /*__cplusplus*/
2989
2990 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
2991 {
2992     log_text("JNI-Call: GetStringRegion");
2993
2994 }
2995
2996 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
2997 {
2998     log_text("JNI-Call: GetStringUTFRegion");
2999
3000 }
3001
3002 /************** obtain direct pointer to array elements ***********************/
3003
3004 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
3005 {
3006         java_objectheader *s = (java_objectheader*) array;
3007         arraydescriptor *desc = s->vftbl->arraydesc;
3008
3009         if (!desc) return NULL;
3010
3011         return ((u1*)s) + desc->dataoffset;
3012 }
3013
3014
3015 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
3016 {
3017         log_text("JNI-Call: ReleasePrimitiveArrayCritical");
3018
3019         /* empty */
3020 }
3021
3022 /**** returns a pointer to an array of Unicode characters of the string *******/
3023
3024 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
3025 {
3026         log_text("JNI-Call: GetStringCritical");
3027
3028         return GetStringChars(env,string,isCopy);
3029 }
3030
3031 /*********** native code no longer needs access to chars **********************/
3032
3033 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
3034 {
3035         log_text("JNI-Call: ReleaseStringCritical");
3036
3037         ReleaseStringChars(env,string,cstring);
3038 }
3039
3040
3041 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3042 {
3043         log_text("JNI-Call: NewWeakGlobalRef");
3044
3045         return obj;
3046 }
3047
3048
3049 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3050 {
3051         log_text("JNI-Call: DeleteWeakGlobalRef");
3052
3053         /* empty */
3054 }
3055
3056
3057 /******************************* check for pending exception ***********************/
3058
3059
3060 jboolean ExceptionCheck(JNIEnv* env)
3061 {
3062         log_text("JNI-Call: ExceptionCheck");
3063
3064         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
3065 }
3066
3067
3068
3069
3070
3071
3072 jint DestroyJavaVM(JavaVM *vm)
3073 {
3074         log_text("DestroyJavaVM called");
3075
3076         return 0;
3077 }
3078
3079
3080 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
3081 {
3082         log_text("AttachCurrentThread called");
3083
3084         return 0;
3085 }
3086
3087
3088 jint DetachCurrentThread(JavaVM *vm)
3089 {
3090         log_text("DetachCurrentThread called");
3091
3092         return 0;
3093 }
3094
3095
3096 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
3097 {
3098         *environment = &env;
3099
3100         return 0;
3101 }
3102
3103
3104 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
3105 {
3106         log_text("AttachCurrentThreadAsDaemon called");
3107
3108         return 0;
3109 }
3110
3111
3112 /********************************* JNI invocation table ******************************/
3113
3114 struct _JavaVM javaVMTable={
3115    NULL,
3116    NULL,
3117    NULL,
3118    &DestroyJavaVM,
3119    &AttachCurrentThread,
3120    &DetachCurrentThread,
3121    &GetEnv,
3122    &AttachCurrentThreadAsDaemon
3123 };
3124
3125 JavaVM javaVM = &javaVMTable;
3126
3127
3128 /********************************* JNI function table ******************************/
3129
3130 struct JNI_Table envTable = {   
3131     NULL,
3132     NULL,
3133     NULL,
3134     NULL,    
3135     &GetVersion,
3136     &DefineClass,
3137     &FindClass,
3138     &FromReflectedMethod,
3139     &FromReflectedField,
3140     &ToReflectedMethod,
3141     &GetSuperclass,
3142     &IsAssignableForm,
3143     &ToReflectedField,
3144     &Throw,
3145     &ThrowNew,
3146     &ExceptionOccurred,
3147     &ExceptionDescribe,
3148     &ExceptionClear,
3149     &FatalError,
3150     &PushLocalFrame,
3151     &PopLocalFrame,
3152     &NewGlobalRef,
3153     &DeleteGlobalRef,
3154     &DeleteLocalRef,
3155     &IsSameObject,
3156     &NewLocalRef,
3157     &EnsureLocalCapacity,
3158     &AllocObject,
3159     &NewObject,
3160     &NewObjectV,
3161     &NewObjectA,
3162     &GetObjectClass,
3163     &IsInstanceOf,
3164     &GetMethodID,
3165     &CallObjectMethod,
3166     &CallObjectMethodV,
3167     &CallObjectMethodA,
3168     &CallBooleanMethod,
3169     &CallBooleanMethodV,
3170     &CallBooleanMethodA,
3171     &CallByteMethod,
3172     &CallByteMethodV,
3173     &CallByteMethodA,
3174     &CallCharMethod,
3175     &CallCharMethodV,
3176     &CallCharMethodA,
3177     &CallShortMethod,
3178     &CallShortMethodV,
3179     &CallShortMethodA,
3180     &CallIntMethod,
3181     &CallIntMethodV,
3182     &CallIntMethodA,
3183     &CallLongMethod,
3184     &CallLongMethodV,
3185     &CallLongMethodA,
3186     &CallFloatMethod,
3187     &CallFloatMethodV,
3188     &CallFloatMethodA,
3189     &CallDoubleMethod,
3190     &CallDoubleMethodV,
3191     &CallDoubleMethodA,
3192     &CallVoidMethod,
3193     &CallVoidMethodV,
3194     &CallVoidMethodA,
3195     &CallNonvirtualObjectMethod,
3196     &CallNonvirtualObjectMethodV,
3197     &CallNonvirtualObjectMethodA,
3198     &CallNonvirtualBooleanMethod,
3199     &CallNonvirtualBooleanMethodV,
3200     &CallNonvirtualBooleanMethodA,
3201     &CallNonvirtualByteMethod,
3202     &CallNonvirtualByteMethodV,
3203     &CallNonvirtualByteMethodA,
3204     &CallNonvirtualCharMethod,
3205     &CallNonvirtualCharMethodV,
3206     &CallNonvirtualCharMethodA,
3207     &CallNonvirtualShortMethod,
3208     &CallNonvirtualShortMethodV,
3209     &CallNonvirtualShortMethodA,
3210     &CallNonvirtualIntMethod,
3211     &CallNonvirtualIntMethodV,
3212     &CallNonvirtualIntMethodA,
3213     &CallNonvirtualLongMethod,
3214     &CallNonvirtualLongMethodV,
3215     &CallNonvirtualLongMethodA,
3216     &CallNonvirtualFloatMethod,
3217     &CallNonvirtualFloatMethodV,
3218     &CallNonvirtualFloatMethodA,
3219     &CallNonvirtualDoubleMethod,
3220     &CallNonvirtualDoubleMethodV,
3221     &CallNonvirtualDoubleMethodA,
3222     &CallNonvirtualVoidMethod,
3223     &CallNonvirtualVoidMethodV,
3224     &CallNonvirtualVoidMethodA,
3225     &GetFieldID,
3226     &GetObjectField,
3227     &GetBooleanField,
3228     &GetByteField,
3229     &GetCharField,
3230     &GetShortField,
3231     &GetIntField,
3232     &GetLongField,
3233     &GetFloatField,
3234     &GetDoubleField,
3235     &SetObjectField,
3236     &SetBooleanField,
3237     &SetByteField,
3238     &SetCharField,
3239     &SetShortField,
3240     &SetIntField,
3241     &SetLongField,
3242     &SetFloatField,
3243     &SetDoubleField,
3244     &GetStaticMethodID,
3245     &CallStaticObjectMethod,
3246     &CallStaticObjectMethodV,
3247     &CallStaticObjectMethodA,
3248     &CallStaticBooleanMethod,
3249     &CallStaticBooleanMethodV,
3250     &CallStaticBooleanMethodA,
3251     &CallStaticByteMethod,
3252     &CallStaticByteMethodV,
3253     &CallStaticByteMethodA,
3254     &CallStaticCharMethod,
3255     &CallStaticCharMethodV,
3256     &CallStaticCharMethodA,
3257     &CallStaticShortMethod,
3258     &CallStaticShortMethodV,
3259     &CallStaticShortMethodA,
3260     &CallStaticIntMethod,
3261     &CallStaticIntMethodV,
3262     &CallStaticIntMethodA,
3263     &CallStaticLongMethod,
3264     &CallStaticLongMethodV,
3265     &CallStaticLongMethodA,
3266     &CallStaticFloatMethod,
3267     &CallStaticFloatMethodV,
3268     &CallStaticFloatMethodA,
3269     &CallStaticDoubleMethod,
3270     &CallStaticDoubleMethodV,
3271     &CallStaticDoubleMethodA,
3272     &CallStaticVoidMethod,
3273     &CallStaticVoidMethodV,
3274     &CallStaticVoidMethodA,
3275     &GetStaticFieldID,
3276     &GetStaticObjectField,
3277     &GetStaticBooleanField,
3278     &GetStaticByteField,
3279     &GetStaticCharField,
3280     &GetStaticShortField,
3281     &GetStaticIntField,
3282     &GetStaticLongField,
3283     &GetStaticFloatField,
3284     &GetStaticDoubleField,
3285     &SetStaticObjectField,
3286     &SetStaticBooleanField,
3287     &SetStaticByteField,
3288     &SetStaticCharField,
3289     &SetStaticShortField,
3290     &SetStaticIntField,
3291     &SetStaticLongField,
3292     &SetStaticFloatField,
3293     &SetStaticDoubleField,
3294     &NewString,
3295     &GetStringLength,
3296     &GetStringChars,
3297     &ReleaseStringChars,
3298     &NewStringUTF,
3299     &GetStringUTFLength,
3300     &GetStringUTFChars,
3301     &ReleaseStringUTFChars,
3302     &GetArrayLength,
3303     &NewObjectArray,
3304     &GetObjectArrayElement,
3305     &SetObjectArrayElement,
3306     &NewBooleanArray,
3307     &NewByteArray,
3308     &NewCharArray,
3309     &NewShortArray,
3310     &NewIntArray,
3311     &NewLongArray,
3312     &NewFloatArray,
3313     &NewDoubleArray,
3314     &GetBooleanArrayElements,
3315     &GetByteArrayElements,
3316     &GetCharArrayElements,
3317     &GetShortArrayElements,
3318     &GetIntArrayElements,
3319     &GetLongArrayElements,
3320     &GetFloatArrayElements,
3321     &GetDoubleArrayElements,
3322     &ReleaseBooleanArrayElements,
3323     &ReleaseByteArrayElements,
3324     &ReleaseCharArrayElements,
3325     &ReleaseShortArrayElements,
3326     &ReleaseIntArrayElements,
3327     &ReleaseLongArrayElements,
3328     &ReleaseFloatArrayElements,
3329     &ReleaseDoubleArrayElements,
3330     &GetBooleanArrayRegion,
3331     &GetByteArrayRegion,
3332     &GetCharArrayRegion,
3333     &GetShortArrayRegion,
3334     &GetIntArrayRegion,
3335     &GetLongArrayRegion,
3336     &GetFloatArrayRegion,
3337     &GetDoubleArrayRegion,
3338     &SetBooleanArrayRegion,
3339     &SetByteArrayRegion,
3340     &SetCharArrayRegion,
3341     &SetShortArrayRegion,
3342     &SetIntArrayRegion,
3343     &SetLongArrayRegion,
3344     &SetFloatArrayRegion,
3345     &SetDoubleArrayRegion,
3346     &RegisterNatives,
3347     &UnregisterNatives,
3348     &MonitorEnter,
3349     &MonitorExit,
3350     &GetJavaVM,
3351     &GetStringRegion,
3352     &GetStringUTFRegion,
3353     &GetPrimitiveArrayCritical,
3354     &ReleasePrimitiveArrayCritical,
3355     &GetStringCritical,
3356     &ReleaseStringCritical,
3357     &NewWeakGlobalRef,
3358     &DeleteWeakGlobalRef,
3359     &ExceptionCheck
3360 };
3361
3362 JNIEnv env = &envTable;
3363
3364
3365 jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
3366 {
3367         int argcount;
3368         jni_callblock *blk;
3369         char retT;
3370         jobject retVal;
3371
3372         if (methodID == 0) {
3373                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
3374                 return NULL;
3375         }
3376
3377         argcount = get_parametercount(methodID);
3378
3379         if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
3380                 *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
3381                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3382                 return 0;
3383         }
3384
3385
3386
3387         if (argcount > 3) {
3388                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3389                 log_text("Too many arguments. invokeNativeHelper does not support that");
3390                 return 0;
3391         }
3392
3393         if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
3394                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
3395                 return 0;
3396         }
3397
3398
3399         if (!(methodID->flags & ACC_STATIC) && (!obj))  {
3400                 *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
3401                                                                                           "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3402                 return 0;
3403         }
3404
3405         if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
3406
3407         blk = MNEW(jni_callblock, 4 /*argcount+2*/);
3408
3409         retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
3410
3411         switch (retT) {
3412         case 'V':
3413                 (void) asm_calljavafunction2(methodID,
3414                                                                          argcount + 1,
3415                                                                          (argcount + 1) * sizeof(jni_callblock),
3416                                                                          blk);
3417                 retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
3418                 break;
3419
3420         case 'I': {
3421                 s4 intVal;      
3422                 intVal = (s4) asm_calljavafunction2(methodID,
3423                                                                                         argcount + 1,
3424                                                                                         (argcount + 1) * sizeof(jni_callblock),
3425                                                                                         blk);
3426                 retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
3427                 CallVoidMethod(env,
3428                                            retVal,
3429                                            class_resolvemethod(retVal->vftbl->class,
3430                                                                                    utf_new_char("<init>"),
3431                                                                                    utf_new_char("(I)V")),
3432                                            intVal);
3433         }
3434         break;
3435
3436         case 'B': {
3437                 s4 intVal;      
3438                 intVal = (s4) asm_calljavafunction2(methodID,
3439                                                                                         argcount + 1,
3440                                                                                         (argcount + 1) * sizeof(jni_callblock),
3441                                                                                         blk);
3442                 retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
3443                 CallVoidMethod(env,
3444                                            retVal,
3445                                            class_resolvemethod(retVal->vftbl->class,
3446                                                                                    utf_new_char("<init>"),
3447                                                                                    utf_new_char("(B)V")),
3448                                            intVal);
3449         }
3450         break;
3451
3452         case 'C': {
3453                 s4 intVal;      
3454                 intVal = (s4) asm_calljavafunction2(methodID,
3455                                                                                         argcount + 1,
3456                                                                                         (argcount + 1) * sizeof(jni_callblock),
3457                                                                                         blk);
3458                 retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
3459                 CallVoidMethod(env,
3460                                            retVal,
3461                                            class_resolvemethod(retVal->vftbl->class,
3462                                                                                    utf_new_char("<init>"),
3463                                                                                    utf_new_char("(C)V")),
3464                                            intVal);
3465         }
3466         break;
3467
3468         case 'S': {
3469                 s4 intVal;      
3470                 intVal = (s4) asm_calljavafunction2(methodID,
3471                                                                                         argcount + 1,
3472                                                                                         (argcount + 1) * sizeof(jni_callblock),
3473                                                                                         blk);
3474                 retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
3475                 CallVoidMethod(env,
3476                                            retVal,
3477                                            class_resolvemethod(retVal->vftbl->class,
3478                                                                                    utf_new_char("<init>"),
3479                                                                                    utf_new_char("(S)V")),
3480                                            intVal);
3481         }
3482         break;
3483
3484         case 'Z': {
3485                 s4 intVal;      
3486                 intVal = (s4) asm_calljavafunction2(methodID,
3487                                                                                         argcount + 1,
3488                                                                                         (argcount + 1) * sizeof(jni_callblock),
3489                                                                                         blk);
3490                 retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
3491                 CallVoidMethod(env,
3492                                            retVal,
3493                                            class_resolvemethod(retVal->vftbl->class,
3494                                                                                    utf_new_char("<init>"),
3495                                                                                    utf_new_char("(Z)V")),
3496                                            intVal);
3497         }
3498         break;
3499
3500         case 'J': {
3501                 jlong intVal;   
3502                 intVal = asm_calljavafunction2long(methodID,
3503                                                                                    argcount + 1,
3504                                                                                    (argcount + 1) * sizeof(jni_callblock),
3505                                                                                    blk);
3506                 retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
3507                 CallVoidMethod(env,
3508                                            retVal,
3509                                            class_resolvemethod(retVal->vftbl->class,
3510                                                                                    utf_new_char("<init>"),
3511                                                                                    utf_new_char("(J)V")),
3512                                            intVal);
3513         }
3514         break;
3515
3516         case 'F': {
3517                 jdouble floatVal;       
3518                 floatVal = asm_calljavafunction2double(methodID,
3519                                                                                            argcount + 1,
3520                                                                                            (argcount + 1) * sizeof(jni_callblock),
3521                                                                                            blk);
3522                 retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
3523                 CallVoidMethod(env,
3524                                            retVal,
3525                                            class_resolvemethod(retVal->vftbl->class,
3526                                                                                    utf_new_char("<init>"),
3527                                                                                    utf_new_char("(F)V")),
3528                                            floatVal);
3529         }
3530         break;
3531
3532         case 'D': {
3533                 jdouble floatVal;       
3534                 floatVal = asm_calljavafunction2double(methodID,
3535                                                                                            argcount + 1,
3536                                                                                            (argcount + 1) * sizeof(jni_callblock),
3537                                                                                            blk);
3538                 retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
3539                 CallVoidMethod(env,
3540                                            retVal,
3541                                            class_resolvemethod(retVal->vftbl->class,
3542                                                                                    utf_new_char("<init>"),
3543                                                                                    utf_new_char("(D)V")),
3544                                            floatVal);
3545         }
3546         break;
3547
3548         case 'L': /* fall through */
3549         case '[':
3550                 retVal = asm_calljavafunction2(methodID,
3551                                                                            argcount + 1,
3552                                                                            (argcount + 1) * sizeof(jni_callblock),
3553                                                                            blk);
3554                 break;
3555
3556         default:
3557                 /* if this happens the acception has already been set by fill_callblock_objA*/
3558                 MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3559                 return (jobject *) 0;
3560         }
3561
3562         MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3563
3564         if (*exceptionptr) {
3565                 java_objectheader *exceptionToWrap = *exceptionptr;
3566                 classinfo *ivtec;
3567                 java_objectheader *ivte;
3568
3569                 *exceptionptr = NULL;
3570                 ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
3571                 ivte = builtin_new(ivtec);
3572                 asm_calljavafunction(class_resolvemethod(ivtec,
3573                                                                                                  utf_new_char("<init>"),
3574                                                                                                  utf_new_char("(Ljava/lang/Throwable;)V")),
3575                                                          ivte,
3576                                                          exceptionToWrap,
3577                                                          0,
3578                                                          0);
3579
3580                 if (*exceptionptr != NULL)
3581                         panic("jni.c: error while creating InvocationTargetException wrapper");
3582
3583                 *exceptionptr = ivte;
3584         }
3585
3586         return (jobject *) retVal;
3587 }
3588
3589
3590 /*
3591  * These are local overrides for various environment variables in Emacs.
3592  * Please do not remove this and leave it at the end of the file, where
3593  * Emacs will automagically detect them.
3594  * ---------------------------------------------------------------------
3595  * Local variables:
3596  * mode: c
3597  * indent-tabs-mode: t
3598  * c-basic-offset: 4
3599  * tab-width: 4
3600  * End:
3601  */