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