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