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