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