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