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