one bug less related to class/exception handing and use_class_as_object. Thanks to...
[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     if (len<0) {
2370                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2371                 return NULL;
2372     }
2373     java_objectarray *j = builtin_anewarray (len, clazz);
2374     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2375     return j;
2376 }
2377
2378 jobject GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
2379 {
2380     jobject j = NULL;
2381
2382     if (index<array->header.size)       
2383         j = array->data[index];
2384     else
2385         exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
2386     
2387     return j;
2388 }
2389
2390 void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject val)
2391 {
2392     if (index>=array->header.size)      
2393         exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
2394     else {
2395
2396         /* check if the class of value is a subclass of the element class of the array */
2397
2398                 if (!builtin_canstore((java_objectarray*)array,(java_objectheader*)val))
2399                         exceptionptr = proto_java_lang_ArrayStoreException;
2400                 else
2401                         array->data[index] = val;
2402     }
2403 }
2404
2405
2406
2407 jbooleanArray NewBooleanArray (JNIEnv *env, jsize len)
2408 {
2409     if (len<0) {
2410                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2411                 return NULL;
2412     }
2413     java_booleanarray *j = builtin_newarray_boolean(len);
2414     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2415     return j;
2416 }
2417
2418
2419 jbyteArray NewByteArray (JNIEnv *env, jsize len)
2420 {
2421     if (len<0) {
2422                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2423                 return NULL;
2424     }
2425     java_bytearray *j = builtin_newarray_byte(len);
2426     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2427     return j;
2428 }
2429
2430
2431 jcharArray NewCharArray (JNIEnv *env, jsize len)
2432 {
2433     if (len<0) {
2434                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2435                 return NULL;
2436     }
2437     java_chararray *j = builtin_newarray_char(len);
2438     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2439     return j;
2440 }
2441
2442
2443 jshortArray NewShortArray (JNIEnv *env, jsize len)
2444 {
2445     if (len<0) {
2446                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2447                 return NULL;
2448     }
2449     java_shortarray *j = builtin_newarray_short(len);   
2450     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2451     return j;
2452 }
2453
2454
2455 jintArray NewIntArray (JNIEnv *env, jsize len)
2456 {
2457     if (len<0) {
2458                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2459                 return NULL;
2460     }
2461     java_intarray *j = builtin_newarray_int(len);
2462     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2463     return j;
2464 }
2465
2466
2467 jlongArray NewLongArray (JNIEnv *env, jsize len)
2468 {
2469     if (len<0) {
2470                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2471                 return NULL;
2472     }
2473     java_longarray *j = builtin_newarray_long(len);
2474     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2475     return j;
2476 }
2477
2478
2479 jfloatArray NewFloatArray (JNIEnv *env, jsize len)
2480 {
2481     if (len<0) {
2482                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2483                 return NULL;
2484     }
2485     java_floatarray *j = builtin_newarray_float(len);
2486     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2487     return j;
2488 }
2489
2490
2491 jdoubleArray NewDoubleArray (JNIEnv *env, jsize len)
2492 {
2493     if (len<0) {
2494                 exceptionptr=proto_java_lang_NegativeArraySizeException;
2495                 return NULL;
2496     }
2497     java_doublearray *j = builtin_newarray_double(len);
2498     if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
2499     return j;
2500 }
2501
2502
2503 jboolean * GetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy)
2504 {
2505     if (isCopy) *isCopy = JNI_FALSE;
2506     return array->data;
2507 }
2508
2509
2510 jbyte * GetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy)
2511 {
2512     if (isCopy) *isCopy = JNI_FALSE;
2513     return array->data;
2514 }
2515
2516
2517 jchar * GetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy)
2518 {
2519     if (isCopy) *isCopy = JNI_FALSE;
2520     return array->data;
2521 }
2522
2523
2524 jshort * GetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy)
2525 {
2526     if (isCopy) *isCopy = JNI_FALSE;
2527     return array->data;
2528 }
2529
2530
2531 jint * GetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy)
2532 {
2533     if (isCopy) *isCopy = JNI_FALSE;
2534     return array->data;
2535 }
2536
2537
2538 jlong * GetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy)
2539 {
2540     if (isCopy) *isCopy = JNI_FALSE;
2541     return array->data;
2542 }
2543
2544
2545 jfloat * GetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy)
2546 {
2547     if (isCopy) *isCopy = JNI_FALSE;
2548     return array->data;
2549 }
2550
2551
2552 jdouble * GetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy)
2553 {
2554     if (isCopy) *isCopy = JNI_FALSE;
2555     return array->data;
2556 }
2557
2558
2559
2560 void ReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode)
2561 {
2562     /* empty */
2563 }
2564
2565
2566 void ReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode)
2567 {
2568     /* empty */
2569 }
2570
2571
2572 void ReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode)
2573 {
2574     /* empty */
2575 }
2576
2577
2578 void ReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode)
2579 {
2580     /* empty */
2581 }
2582
2583
2584 void ReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode)
2585 {
2586     /* empty */
2587 }
2588
2589
2590 void ReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode)
2591 {
2592     /* empty */
2593 }
2594
2595
2596 void ReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode)
2597 {
2598     /* empty */
2599 }
2600
2601
2602 void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode)
2603 {
2604     /* empty */
2605 }
2606
2607 void GetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2608 {
2609     if (start<0 || len<0 || start+len>array->header.size)
2610         exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
2611     else
2612         memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
2613 }
2614
2615
2616 void GetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *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 GetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *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 GetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *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 GetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *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 GetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 GetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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 GetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *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 SetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
2680 {
2681     if (start<0 || len<0 || start+len>array->header.size)
2682         exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
2683     else
2684         memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
2685 }
2686
2687
2688 void SetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *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 SetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *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
2707 void SetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
2708 {
2709     if (start<0 || len<0 || start+len>array->header.size)
2710         exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
2711     else
2712         memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
2713 }
2714
2715
2716 void SetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *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 SetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *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 SetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *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 SetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *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 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
2752 {
2753     log_text("JNI-Call: RegisterNatives");
2754     return 0;
2755 }
2756
2757
2758 jint UnregisterNatives (JNIEnv* env, jclass clazz)
2759 {
2760     log_text("JNI-Call: UnregisterNatives");
2761     return 0;
2762 }
2763
2764 /******************************* monitor operations ********************************/
2765
2766 jint MonitorEnter (JNIEnv* env, jobject obj)
2767 {
2768     builtin_monitorenter(obj);
2769     return 0;
2770 }
2771
2772
2773 jint MonitorExit (JNIEnv* env, jobject obj)
2774 {
2775     builtin_monitorexit(obj);
2776     return 0;
2777 }
2778
2779
2780 /************************************* JavaVM interface ****************************/
2781 #ifdef __cplusplus
2782 #error CPP mode not supported yet
2783 #else
2784 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
2785 {
2786     log_text("JNI-Call: GetJavaVM");
2787     *vm=&javaVM;
2788     return 0;
2789 }
2790 #endif /*__cplusplus*/
2791
2792 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
2793 {
2794     log_text("JNI-Call: GetStringRegion");
2795
2796 }
2797
2798 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
2799 {
2800     log_text("JNI-Call: GetStringUTFRegion");
2801
2802 }
2803
2804 /****************** obtain direct pointer to array elements ***********************/
2805
2806 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
2807 {
2808         java_objectheader *s = (java_objectheader*) array;
2809         arraydescriptor *desc = s->vftbl->arraydesc;
2810
2811         if (!desc) return NULL;
2812
2813         return ((u1*)s) + desc->dataoffset;
2814 }
2815
2816
2817 void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jint mode)
2818 {
2819         log_text("JNI-Call: ReleasePrimitiveArrayCritical");
2820
2821         /* empty */
2822 }
2823
2824 /********* returns a pointer to an array of Unicode characters of the string *******/
2825
2826 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
2827 {
2828         log_text("JNI-Call: GetStringCritical");
2829
2830         return GetStringChars(env,string,isCopy);
2831 }
2832
2833 /**************** native code no longer needs access to chars **********************/
2834
2835 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
2836 {
2837         log_text("JNI-Call: ReleaseStringCritical");
2838
2839         ReleaseStringChars(env,string,cstring);
2840 }
2841
2842
2843 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
2844 {
2845         log_text("JNI-Call: NewWeakGlobalRef");
2846
2847         return obj;
2848 }
2849
2850
2851 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
2852 {
2853         log_text("JNI-Call: DeleteWeakGlobalRef");
2854
2855         /* empty */
2856 }
2857
2858
2859 /******************************* check for pending exception ***********************/
2860
2861
2862 jboolean ExceptionCheck(JNIEnv* env)
2863 {
2864         log_text("JNI-Call: ExceptionCheck");
2865
2866         return exceptionptr ? JNI_TRUE : JNI_FALSE;
2867 }
2868
2869
2870
2871
2872
2873
2874 jint DestroyJavaVM(JavaVM *vm)
2875 {
2876         log_text("DestroyJavaVM called");
2877
2878         return 0;
2879 }
2880
2881
2882 jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2)
2883 {
2884         log_text("AttachCurrentThread called");
2885
2886         return 0;
2887 }
2888
2889
2890 jint DetachCurrentThread(JavaVM *vm)
2891 {
2892         log_text("DetachCurrentThread called");
2893
2894         return 0;
2895 }
2896
2897
2898 jint GetEnv(JavaVM *vm, void **environment, jint jniversion)
2899 {
2900         *environment = &env;
2901
2902         return 0;
2903 }
2904
2905
2906 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
2907 {
2908         log_text("AttachCurrentThreadAsDaemon called");
2909
2910         return 0;
2911 }
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923 /********************************* JNI invocation table ******************************/
2924
2925 struct _JavaVM javaVMTable={
2926    NULL,
2927    NULL,
2928    NULL,
2929    &DestroyJavaVM,
2930    &AttachCurrentThread,
2931    &DetachCurrentThread,
2932    &GetEnv,
2933    &AttachCurrentThreadAsDaemon
2934 };
2935
2936 JavaVM javaVM = &javaVMTable;
2937
2938
2939 /********************************* JNI function table ******************************/
2940
2941 struct JNI_Table envTable = {   
2942     NULL,
2943     NULL,
2944     NULL,
2945     NULL,    
2946     &GetVersion,
2947     &DefineClass,
2948     &FindClass,
2949     &FromReflectedMethod,
2950     &FromReflectedField,
2951     &ToReflectedMethod,
2952     &GetSuperclass,
2953     &IsAssignableForm,
2954     &ToReflectedField,
2955     &Throw,
2956     &ThrowNew,
2957     &ExceptionOccurred,
2958     &ExceptionDescribe,
2959     &ExceptionClear,
2960     &FatalError,
2961     &PushLocalFrame,
2962     &PopLocalFrame,
2963     &NewGlobalRef,
2964     &DeleteGlobalRef,
2965     &DeleteLocalRef,
2966     &IsSameObject,
2967     &NewLocalRef,
2968     &EnsureLocalCapacity,
2969     &AllocObject,
2970     &NewObject,
2971     &NewObjectV,
2972     &NewObjectA,
2973     &GetObjectClass,
2974     &IsInstanceOf,
2975     &GetMethodID,
2976     &CallObjectMethod,
2977     &CallObjectMethodV,
2978     &CallObjectMethodA,
2979     &CallBooleanMethod,
2980     &CallBooleanMethodV,
2981     &CallBooleanMethodA,
2982     &CallByteMethod,
2983     &CallByteMethodV,
2984     &CallByteMethodA,
2985     &CallCharMethod,
2986     &CallCharMethodV,
2987     &CallCharMethodA,
2988     &CallShortMethod,
2989     &CallShortMethodV,
2990     &CallShortMethodA,
2991     &CallIntMethod,
2992     &CallIntMethodV,
2993     &CallIntMethodA,
2994     &CallLongMethod,
2995     &CallLongMethodV,
2996     &CallLongMethodA,
2997     &CallFloatMethod,
2998     &CallFloatMethodV,
2999     &CallFloatMethodA,
3000     &CallDoubleMethod,
3001     &CallDoubleMethodV,
3002     &CallDoubleMethodA,
3003     &CallVoidMethod,
3004     &CallVoidMethodV,
3005     &CallVoidMethodA,
3006     &CallNonvirtualObjectMethod,
3007     &CallNonvirtualObjectMethodV,
3008     &CallNonvirtualObjectMethodA,
3009     &CallNonvirtualBooleanMethod,
3010     &CallNonvirtualBooleanMethodV,
3011     &CallNonvirtualBooleanMethodA,
3012     &CallNonvirtualByteMethod,
3013     &CallNonvirtualByteMethodV,
3014     &CallNonvirtualByteMethodA,
3015     &CallNonvirtualCharMethod,
3016     &CallNonvirtualCharMethodV,
3017     &CallNonvirtualCharMethodA,
3018     &CallNonvirtualShortMethod,
3019     &CallNonvirtualShortMethodV,
3020     &CallNonvirtualShortMethodA,
3021     &CallNonvirtualIntMethod,
3022     &CallNonvirtualIntMethodV,
3023     &CallNonvirtualIntMethodA,
3024     &CallNonvirtualLongMethod,
3025     &CallNonvirtualLongMethodV,
3026     &CallNonvirtualLongMethodA,
3027     &CallNonvirtualFloatMethod,
3028     &CallNonvirtualFloatMethodV,
3029     &CallNonvirtualFloatMethodA,
3030     &CallNonvirtualDoubleMethod,
3031     &CallNonvirtualDoubleMethodV,
3032     &CallNonvirtualDoubleMethodA,
3033     &CallNonvirtualVoidMethod,
3034     &CallNonvirtualVoidMethodV,
3035     &CallNonvirtualVoidMethodA,
3036     &GetFieldID,
3037     &GetObjectField,
3038     &GetBooleanField,
3039     &GetByteField,
3040     &GetCharField,
3041     &GetShortField,
3042     &GetIntField,
3043     &GetLongField,
3044     &GetFloatField,
3045     &GetDoubleField,
3046     &SetObjectField,
3047     &SetBooleanField,
3048     &SetByteField,
3049     &SetCharField,
3050     &SetShortField,
3051     &SetIntField,
3052     &SetLongField,
3053     &SetFloatField,
3054     &SetDoubleField,
3055     &GetStaticMethodID,
3056     &CallStaticObjectMethod,
3057     &CallStaticObjectMethodV,
3058     &CallStaticObjectMethodA,
3059     &CallStaticBooleanMethod,
3060     &CallStaticBooleanMethodV,
3061     &CallStaticBooleanMethodA,
3062     &CallStaticByteMethod,
3063     &CallStaticByteMethodV,
3064     &CallStaticByteMethodA,
3065     &CallStaticCharMethod,
3066     &CallStaticCharMethodV,
3067     &CallStaticCharMethodA,
3068     &CallStaticShortMethod,
3069     &CallStaticShortMethodV,
3070     &CallStaticShortMethodA,
3071     &CallStaticIntMethod,
3072     &CallStaticIntMethodV,
3073     &CallStaticIntMethodA,
3074     &CallStaticLongMethod,
3075     &CallStaticLongMethodV,
3076     &CallStaticLongMethodA,
3077     &CallStaticFloatMethod,
3078     &CallStaticFloatMethodV,
3079     &CallStaticFloatMethodA,
3080     &CallStaticDoubleMethod,
3081     &CallStaticDoubleMethodV,
3082     &CallStaticDoubleMethodA,
3083     &CallStaticVoidMethod,
3084     &CallStaticVoidMethodV,
3085     &CallStaticVoidMethodA,
3086     &GetStaticFieldID,
3087     &GetStaticObjectField,
3088     &GetStaticBooleanField,
3089     &GetStaticByteField,
3090     &GetStaticCharField,
3091     &GetStaticShortField,
3092     &GetStaticIntField,
3093     &GetStaticLongField,
3094     &GetStaticFloatField,
3095     &GetStaticDoubleField,
3096     &SetStaticObjectField,
3097     &SetStaticBooleanField,
3098     &SetStaticByteField,
3099     &SetStaticCharField,
3100     &SetStaticShortField,
3101     &SetStaticIntField,
3102     &SetStaticLongField,
3103     &SetStaticFloatField,
3104     &SetStaticDoubleField,
3105     &NewString,
3106     &GetStringLength,
3107     &GetStringChars,
3108     &ReleaseStringChars,
3109     &NewStringUTF,
3110     &GetStringUTFLength,
3111     &GetStringUTFChars,
3112     &ReleaseStringUTFChars,
3113     &GetArrayLength,
3114     &NewObjectArray,
3115     &GetObjectArrayElement,
3116     &SetObjectArrayElement,
3117     &NewBooleanArray,
3118     &NewByteArray,
3119     &NewCharArray,
3120     &NewShortArray,
3121     &NewIntArray,
3122     &NewLongArray,
3123     &NewFloatArray,
3124     &NewDoubleArray,
3125     &GetBooleanArrayElements,
3126     &GetByteArrayElements,
3127     &GetCharArrayElements,
3128     &GetShortArrayElements,
3129     &GetIntArrayElements,
3130     &GetLongArrayElements,
3131     &GetFloatArrayElements,
3132     &GetDoubleArrayElements,
3133     &ReleaseBooleanArrayElements,
3134     &ReleaseByteArrayElements,
3135     &ReleaseCharArrayElements,
3136     &ReleaseShortArrayElements,
3137     &ReleaseIntArrayElements,
3138     &ReleaseLongArrayElements,
3139     &ReleaseFloatArrayElements,
3140     &ReleaseDoubleArrayElements,
3141     &GetBooleanArrayRegion,
3142     &GetByteArrayRegion,
3143     &GetCharArrayRegion,
3144     &GetShortArrayRegion,
3145     &GetIntArrayRegion,
3146     &GetLongArrayRegion,
3147     &GetFloatArrayRegion,
3148     &GetDoubleArrayRegion,
3149     &SetBooleanArrayRegion,
3150     &SetByteArrayRegion,
3151     &SetCharArrayRegion,
3152     &SetShortArrayRegion,
3153     &SetIntArrayRegion,
3154     &SetLongArrayRegion,
3155     &SetFloatArrayRegion,
3156     &SetDoubleArrayRegion,
3157     &RegisterNatives,
3158     &UnregisterNatives,
3159     &MonitorEnter,
3160     &MonitorExit,
3161     &GetJavaVM,
3162     &GetStringRegion,
3163     &GetStringUTFRegion,
3164     &GetPrimitiveArrayCritical,
3165     &ReleasePrimitiveArrayCritical,
3166     &GetStringCritical,
3167     &ReleaseStringCritical,
3168     &NewWeakGlobalRef,
3169     &DeleteWeakGlobalRef,
3170     &ExceptionCheck
3171 };
3172
3173
3174 JNIEnv env = &envTable;
3175
3176
3177
3178
3179
3180
3181
3182
3183 jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,jobject obj, java_objectarray *params) {
3184         int argcount;
3185         jni_callblock *blk;
3186         jobject ret;
3187         char retT;
3188         jobject retVal;
3189         if (methodID==0) {
3190                 exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
3191                 return 0;
3192         }
3193         argcount=get_parametercount(methodID);
3194
3195         if (obj && (!builtin_instanceof((java_objectheader*)obj,methodID->class))) {
3196                 (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/IllegalArgumentException")),
3197                         "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
3198                 return 0;
3199         }
3200
3201
3202
3203         if  (argcount>3) {
3204                 exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
3205                 log_text("Too many arguments. invokeNativeHelper does not support that");
3206                 return 0;
3207         }
3208
3209         if ( ((!params) && (argcount!=0)) || 
3210                 (params && (params->header.size!=argcount))
3211            ) {
3212                 exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
3213                 return 0;
3214         }
3215
3216
3217          if (!(methodID->flags & ACC_STATIC) && (!obj))  {
3218                 (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/NullPointerException")),
3219                         "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
3220                 return 0;
3221         }
3222
3223         if ((methodID->flags & ACC_STATIC) && (obj)) obj=0;
3224
3225         blk = MNEW(jni_callblock, 4 /*argcount+2*/);
3226
3227         retT=fill_callblock_objA(obj,methodID->descriptor,blk,params);
3228
3229         switch (retT) {
3230                 case 'V':       (void)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
3231                                 retVal=native_new_and_init(loader_load(utf_new_char("java/lang/Void")));
3232                                 break;
3233                 case 'I':       {
3234                                         s4 intVal;      
3235                                         intVal=(s4)asm_calljavafunction2(methodID,
3236                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3237                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Integer")));
3238                                         CallVoidMethod(env,retVal,
3239                                                 class_resolvemethod(retVal->vftbl->class,
3240                                                 utf_new_char("<init>"),utf_new_char("(I)V")),intVal);
3241                                 }
3242                                 break;
3243                 case 'B':       {
3244                                         s4 intVal;      
3245                                         intVal=(s4)asm_calljavafunction2(methodID,
3246                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3247                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Byte")));
3248                                         CallVoidMethod(env,retVal,
3249                                                 class_resolvemethod(retVal->vftbl->class,
3250                                                 utf_new_char("<init>"),utf_new_char("(B)V")),intVal);
3251                                 }
3252                                 break;
3253                 case 'C':       {
3254                                         s4 intVal;      
3255                                         intVal=(s4)asm_calljavafunction2(methodID,
3256                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3257                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Character")));
3258                                         CallVoidMethod(env,retVal,
3259                                                 class_resolvemethod(retVal->vftbl->class,
3260                                                 utf_new_char("<init>"),utf_new_char("(C)V")),intVal);
3261                                 }
3262                                 break;
3263                 case 'S':       {
3264                                         s4 intVal;      
3265                                         intVal=(s4)asm_calljavafunction2(methodID,
3266                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3267                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Short")));
3268                                         CallVoidMethod(env,retVal,
3269                                                 class_resolvemethod(retVal->vftbl->class,
3270                                                 utf_new_char("<init>"),utf_new_char("(S)V")),intVal);
3271                                 }
3272
3273                 case 'Z':       {
3274                                         s4 intVal;      
3275                                         intVal=(s4)asm_calljavafunction2(methodID,
3276                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3277                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Boolean")));
3278                                         CallVoidMethod(env,retVal,
3279                                                 class_resolvemethod(retVal->vftbl->class,
3280                                                 utf_new_char("<init>"),utf_new_char("(Z)V")),intVal);
3281                                 }
3282                                 break;
3283                 case 'J':       {
3284                                         jlong intVal;   
3285                                         intVal=asm_calljavafunction2long(methodID,
3286                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3287                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Long")));
3288                                         CallVoidMethod(env,retVal,
3289                                                 class_resolvemethod(retVal->vftbl->class,
3290                                                 utf_new_char("<init>"),utf_new_char("(J)V")),intVal);
3291                                 }
3292                                 break;
3293                 case 'F':       {
3294                                         jdouble floatVal;       
3295                                         floatVal=asm_calljavafunction2double(methodID,
3296                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3297                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Float")));
3298                                         CallVoidMethod(env,retVal,
3299                                                 class_resolvemethod(retVal->vftbl->class,
3300                                                 utf_new_char("<init>"),utf_new_char("(F)V")),floatVal);
3301                                 }
3302                                 break;
3303                 case 'D':       {
3304                                         jdouble floatVal;       
3305                                         floatVal=asm_calljavafunction2double(methodID,
3306                                                 argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
3307                                         retVal=builtin_new(loader_load(utf_new_char("java/lang/Double")));
3308                                         CallVoidMethod(env,retVal,
3309                                                 class_resolvemethod(retVal->vftbl->class,
3310                                                 utf_new_char("<init>"),utf_new_char("(D)V")),floatVal);
3311                                 }
3312                                 break;
3313
3314                 case 'L':       /* fall through */
3315                 case '[':       retVal=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
3316                                 break;
3317                 default:        { 
3318                                         /* if this happens the acception has already been set by fill_callblock_objA*/
3319                                         MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3320                                         return (jobject*)0;
3321                                 }
3322         }
3323         MFREE(blk, jni_callblock, 4 /*argcount+2*/);
3324
3325         if (exceptionptr)
3326                 exceptionptr=native_new_and_init(loader_load("java/lang/reflect/InvocationTargetException"));
3327         return retVal;  
3328
3329 }
3330
3331
3332
3333 /*
3334  * These are local overrides for various environment variables in Emacs.
3335  * Please do not remove this and leave it at the end of the file, where
3336  * Emacs will automagically detect them.
3337  * ---------------------------------------------------------------------
3338  * Local variables:
3339  * mode: c
3340  * indent-tabs-mode: t
3341  * c-basic-offset: 4
3342  * tab-width: 4
3343  * End:
3344  */