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