* NewLocalRef: Keep the compiler happy, return a value.
[cacao.git] / src / native / jni.c
1 /* src/native/jni.c - implementation of the Java Native Interface functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Rainhard Grafl
28             Roman Obermaisser
29
30    Changes: Joseph Wenninger
31             Martin Platter
32             Christian Thalinger
33
34    $Id: jni.c 3434 2005-10-13 16:10:12Z twisti $
35
36 */
37
38
39 #include <assert.h>
40 #include <string.h>
41
42 #include "config.h"
43
44 #include "mm/boehm.h"
45 #include "mm/memory.h"
46 #include "native/jni.h"
47 #include "native/native.h"
48
49 #include "native/include/gnu_classpath_Pointer.h"
50
51 #if SIZEOF_VOID_P == 8
52 # include "native/include/gnu_classpath_Pointer64.h"
53 #else
54 # include "native/include/gnu_classpath_Pointer32.h"
55 #endif
56
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_Byte.h"
59 #include "native/include/java_lang_Character.h"
60 #include "native/include/java_lang_Short.h"
61 #include "native/include/java_lang_Integer.h"
62 #include "native/include/java_lang_Boolean.h"
63 #include "native/include/java_lang_Long.h"
64 #include "native/include/java_lang_Float.h"
65 #include "native/include/java_lang_Double.h"
66 #include "native/include/java_lang_Throwable.h"
67 #include "native/include/java_lang_reflect_Method.h"
68 #include "native/include/java_lang_reflect_Constructor.h"
69 #include "native/include/java_lang_reflect_Field.h"
70
71 #include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
72 #include "native/include/java_lang_VMClass.h"
73 #include "native/include/java_lang_VMClassLoader.h"
74 #include "native/include/java_nio_Buffer.h"
75 #include "native/include/java_nio_DirectByteBufferImpl.h"
76
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/jvmti.h"
79 #endif
80
81 #if defined(USE_THREADS)
82 # if defined(NATIVE_THREADS)
83 #  include "threads/native/threads.h"
84 # else
85 #  include "threads/green/threads.h"
86 # endif
87 #endif
88
89 #include "toolbox/logging.h"
90 #include "vm/builtin.h"
91 #include "vm/exceptions.h"
92 #include "vm/global.h"
93 #include "vm/initialize.h"
94 #include "vm/loader.h"
95 #include "vm/options.h"
96 #include "vm/resolve.h"
97 #include "vm/statistics.h"
98 #include "vm/stringlocal.h"
99 #include "vm/tables.h"
100 #include "vm/jit/asmpart.h"
101 #include "vm/jit/jit.h"
102 #include "vm/statistics.h"
103
104
105 /* XXX TWISTI hack: define it extern so they can be found in this file */
106
107 extern const struct JNIInvokeInterface JNI_JavaVMTable;
108 extern struct JNINativeInterface JNI_JNIEnvTable;
109
110 /* pointers to VM and the environment needed by GetJavaVM and GetEnv */
111
112 static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
113 void *ptr_env = (void*) &JNI_JNIEnvTable;
114
115
116 #define PTR_TO_ITEM(ptr)   ((u8)(size_t)(ptr))
117
118 /* global variables ***********************************************************/
119
120 /* global reference table *****************************************************/
121
122 static java_objectheader **global_ref_table;
123
124 /* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
125 static classinfo *ihmclass = NULL;
126 static methodinfo *putmid = NULL;
127 static methodinfo *getmid = NULL;
128 static methodinfo *removemid = NULL;
129
130
131 /* direct buffer stuff ********************************************************/
132
133 static utf *utf_java_nio_DirectByteBufferImpl;
134 #if SIZEOF_VOID_P == 8
135 static utf *utf_gnu_classpath_Pointer64;
136 #else
137 static utf *utf_gnu_classpath_Pointer32;
138 #endif
139
140 static classinfo *class_java_nio_DirectByteBufferImpl;
141 #if SIZEOF_VOID_P == 8
142 static classinfo *class_gnu_classpath_Pointer64;
143 #else
144 static classinfo *class_gnu_classpath_Pointer32;
145 #endif
146
147
148 /* local reference table ******************************************************/
149
150 #if defined(USE_THREADS)
151 #define LOCALREFTABLE    (THREADINFO->_localref_table)
152 #else
153 #define LOCALREFTABLE    (_no_threads_localref_table)
154 #endif
155
156 #if !defined(USE_THREADS)
157 static localref_table *_no_threads_localref_table;
158 #endif
159
160
161 /********************* accessing instance-fields **********************************/
162
163 #define setField(obj,typ,var,val) *((typ*) ((long int) obj + (long int) var->offset))=val;  
164 #define getField(obj,typ,var)     *((typ*) ((long int) obj + (long int) var->offset))
165 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) \
166     setField(obj, jdatatype, getFieldID_critical(env,clazz,name,sig), val);
167
168
169 /* some forward declarations **************************************************/
170
171 jobject NewLocalRef(JNIEnv *env, jobject ref);
172
173
174 /* jni_init ********************************************************************
175
176    Initialize the JNI subsystem.
177
178 *******************************************************************************/
179
180 bool jni_init(void)
181 {
182         /* initalize global reference table */
183
184         if (!(ihmclass =
185                   load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
186                 return false;
187
188         global_ref_table = GCNEW(jobject, 1);
189
190         if (!(*global_ref_table = native_new_and_init(ihmclass)))
191                 return false;
192
193         if (!(getmid = class_resolvemethod(ihmclass, utf_get,
194                                                                            utf_java_lang_Object__java_lang_Object)))
195                 return false;
196
197         if (!(putmid = class_resolvemethod(ihmclass, utf_put,
198                                                                            utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
199                 return false;
200
201         if (!(removemid =
202                   class_resolvemethod(ihmclass, utf_remove,
203                                                           utf_java_lang_Object__java_lang_Object)))
204                 return false;
205
206
207         /* direct buffer stuff */
208
209         utf_java_nio_DirectByteBufferImpl =
210                 utf_new_char("java/nio/DirectByteBufferImpl");
211
212         if (!(class_java_nio_DirectByteBufferImpl =
213                   load_class_bootstrap(utf_java_nio_DirectByteBufferImpl)))
214                 return false;
215
216         if (!link_class(class_java_nio_DirectByteBufferImpl))
217                 return false;
218
219 #if SIZEOF_VOID_P == 8
220         utf_gnu_classpath_Pointer64 = utf_new_char("gnu/classpath/Pointer64");
221
222         if (!(class_gnu_classpath_Pointer64 =
223                   load_class_bootstrap(utf_gnu_classpath_Pointer64)))
224                 return false;
225
226         if (!link_class(class_gnu_classpath_Pointer64))
227                 return false;
228 #else
229         utf_gnu_classpath_Pointer32 = utf_new_char("gnu/classpath/Pointer32");
230
231         if (!(class_gnu_classpath_Pointer32 =
232                   load_class_bootstrap(utf_gnu_classpath_Pointer32)))
233                 return false;
234
235         if (!link_class(class_gnu_classpath_Pointer32))
236                 return false;
237 #endif
238
239         return true;
240 }
241
242
243 static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
244                                                                           jni_callblock blk[], va_list data,
245                                                                           s4 rettype)
246 {
247         typedesc *paramtypes;
248         s4        i;
249
250         paramtypes = descr->paramtypes;
251
252         /* if method is non-static fill first block and skip `this' pointer */
253
254         i = 0;
255
256         if (obj) {
257                 /* the `this' pointer */
258                 blk[0].itemtype = TYPE_ADR;
259                 blk[0].item = PTR_TO_ITEM(obj);
260
261                 paramtypes++;
262                 i++;
263         } 
264
265         for (; i < descr->paramcount; i++, paramtypes++) {
266                 switch (paramtypes->decltype) {
267                 /* primitive types */
268                 case PRIMITIVETYPE_BYTE:
269                 case PRIMITIVETYPE_CHAR:
270                 case PRIMITIVETYPE_SHORT: 
271                 case PRIMITIVETYPE_BOOLEAN: 
272                         blk[i].itemtype = TYPE_INT;
273                         blk[i].item = (s8) va_arg(data, s4);
274                         break;
275
276                 case PRIMITIVETYPE_INT:
277                         blk[i].itemtype = TYPE_INT;
278                         blk[i].item = (s8) va_arg(data, s4);
279                         break;
280
281                 case PRIMITIVETYPE_LONG:
282                         blk[i].itemtype = TYPE_LNG;
283                         blk[i].item = (s8) va_arg(data, s8);
284                         break;
285
286                 case PRIMITIVETYPE_FLOAT:
287                         blk[i].itemtype = TYPE_FLT;
288 #if defined(__ALPHA__)
289                         /* this keeps the assembler function much simpler */
290
291                         *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
292 #else
293                         *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
294 #endif
295                         break;
296
297                 case PRIMITIVETYPE_DOUBLE:
298                         blk[i].itemtype = TYPE_DBL;
299                         *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
300                         break;
301
302                 case TYPE_ADR: 
303                         blk[i].itemtype = TYPE_ADR;
304                         blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
305                         break;
306                 }
307         }
308
309         /* The standard doesn't say anything about return value checking, but it  */
310         /* appears to be useful.                                                  */
311
312         if (rettype != descr->returntype.decltype)
313                 log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
314 }
315
316
317 /* XXX it could be considered if we should do typechecking here in the future */
318
319 static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
320                                                                                         jni_callblock blk[],
321                                                                                         java_objectarray *params)
322 {
323     jobject    param;
324         s4         paramcount;
325         typedesc  *paramtypes;
326         classinfo *c;
327     s4         i;
328         s4         j;
329
330         paramcount = descr->paramcount;
331         paramtypes = descr->paramtypes;
332
333         /* if method is non-static fill first block and skip `this' pointer */
334
335         i = 0;
336
337         if (obj) {
338                 /* this pointer */
339                 blk[0].itemtype = TYPE_ADR;
340                 blk[0].item = PTR_TO_ITEM(obj);
341
342                 paramtypes++;
343                 paramcount--;
344                 i++;
345         }
346
347         for (j = 0; j < paramcount; i++, j++, paramtypes++) {
348                 switch (paramtypes->type) {
349                 /* primitive types */
350                 case TYPE_INT:
351                 case TYPE_LONG:
352                 case TYPE_FLOAT:
353                 case TYPE_DOUBLE:
354                         param = params->data[j];
355                         if (!param)
356                                 goto illegal_arg;
357
358                         /* internally used data type */
359                         blk[i].itemtype = paramtypes->type;
360
361                         /* convert the value according to its declared type */
362
363                         c = param->vftbl->class;
364
365                         switch (paramtypes->decltype) {
366                         case PRIMITIVETYPE_BOOLEAN:
367                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
368                                         blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
369                                 else
370                                         goto illegal_arg;
371                                 break;
372
373                         case PRIMITIVETYPE_BYTE:
374                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
375                                         blk[i].item = (s8) ((java_lang_Byte *) param)->value;
376                                 else
377                                         goto illegal_arg;
378                                 break;
379
380                         case PRIMITIVETYPE_CHAR:
381                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
382                                         blk[i].item = (s8) ((java_lang_Character *) param)->value;
383                                 else
384                                         goto illegal_arg;
385                                 break;
386
387                         case PRIMITIVETYPE_SHORT:
388                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
389                                         blk[i].item = (s8) ((java_lang_Short *) param)->value;
390                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
391                                         blk[i].item = (s8) ((java_lang_Byte *) param)->value;
392                                 else
393                                         goto illegal_arg;
394                                 break;
395
396                         case PRIMITIVETYPE_INT:
397                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
398                                         blk[i].item = (s8) ((java_lang_Integer *) param)->value;
399                                 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
400                                         blk[i].item = (s8) ((java_lang_Short *) param)->value;
401                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
402                                         blk[i].item = (s8) ((java_lang_Byte *) param)->value;
403                                 else
404                                         goto illegal_arg;
405                                 break;
406
407                         case PRIMITIVETYPE_LONG:
408                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
409                                         blk[i].item = (s8) ((java_lang_Long *) param)->value;
410                                 else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
411                                         blk[i].item = (s8) ((java_lang_Integer *) param)->value;
412                                 else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
413                                         blk[i].item = (s8) ((java_lang_Short *) param)->value;
414                                 else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
415                                         blk[i].item = (s8) ((java_lang_Byte *) param)->value;
416                                 else
417                                         goto illegal_arg;
418                                 break;
419
420                         case PRIMITIVETYPE_FLOAT:
421                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
422                                         *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
423                                 else
424                                         goto illegal_arg;
425                                 break;
426
427                         case PRIMITIVETYPE_DOUBLE:
428                                 if (c == primitivetype_table[paramtypes->decltype].class_wrap)
429                                         *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Float *) param)->value;
430                                 else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
431                                         *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
432                                 else
433                                         goto illegal_arg;
434                                 break;
435
436                         default:
437                                 goto illegal_arg;
438                         } /* end declared type switch */
439                         break;
440                 
441                         case TYPE_ADDRESS:
442                                 if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
443                                         return false;
444
445                                 if (params->data[j] != 0) {
446                                         if (paramtypes->arraydim > 0) {
447                                                 if (!builtin_arrayinstanceof(params->data[j], c->vftbl))
448                                                         goto illegal_arg;
449
450                                         } else {
451                                                 if (!builtin_instanceof(params->data[j], c))
452                                                         goto illegal_arg;
453                                         }
454                                 }
455                                 blk[i].itemtype = TYPE_ADR;
456                                 blk[i].item = PTR_TO_ITEM(params->data[j]);
457                                 break;                  
458
459                         default:
460                                 goto illegal_arg;
461                 } /* end param type switch */
462
463         } /* end param loop */
464
465 /*      if (rettype) */
466 /*              *rettype = descr->returntype.decltype; */
467
468         return true;
469
470 illegal_arg:
471         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
472         return false;
473 }
474
475
476 static jmethodID get_virtual(jobject obj, jmethodID methodID)
477 {
478         if (obj->vftbl->class == methodID->class)
479                 return methodID;
480
481         return class_resolvemethod(obj->vftbl->class, methodID->name,
482                                                            methodID->descriptor);
483 }
484
485
486 static jmethodID get_nonvirtual(jclass clazz, jmethodID methodID)
487 {
488         if (clazz == methodID->class)
489                 return methodID;
490
491         /* class_resolvemethod -> classfindmethod? (JOWENN) */
492         return class_resolvemethod(clazz, methodID->name, methodID->descriptor);
493 }
494
495
496 static jobject callObjectMethod(jobject obj, jmethodID methodID, va_list args)
497 {       
498         int argcount;
499         jni_callblock *blk;
500         jobject ret;
501
502         if (methodID == 0) {
503                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
504                 return 0;
505         }
506
507         if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
508                 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
509                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
510                 return 0;
511         }
512
513         if (obj && !builtin_instanceof(obj, methodID->class)) {
514                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
515                 return 0;
516         }
517
518         argcount = methodID->parseddesc->paramcount;
519
520         blk = MNEW(jni_callblock, argcount);
521
522         fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_ADR);
523
524         STATS(jnicallXmethodnvokation();)
525
526         ret = asm_calljavafunction2(methodID,
527                                                                 argcount,
528                                                                 argcount * sizeof(jni_callblock),
529                                                                 blk);
530
531         MFREE(blk, jni_callblock, argcount);
532
533         return ret;
534 }
535
536
537 /*
538   core function for integer class methods (bool, byte, short, integer)
539   This is basically needed for i386
540 */
541 static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
542 {
543         int argcount;
544         jni_callblock *blk;
545         jint ret;
546
547         STATS(jniinvokation();)
548
549         /*
550         log_text("JNI-Call: CallObjectMethodV");
551         utf_display(methodID->name);
552         utf_display(methodID->descriptor);
553         printf("\nParmaeter count: %d\n",argcount);
554         utf_display(obj->vftbl->class->name);
555         printf("\n");
556         */
557         if (methodID == 0) {
558                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
559                 return 0;
560         }
561         
562         if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
563                 ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
564                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
565                 return 0;
566         }
567
568         if (obj && !builtin_instanceof(obj, methodID->class)) {
569                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
570                 return 0;
571         }
572
573         argcount = methodID->parseddesc->paramcount;
574
575         blk = MNEW(jni_callblock, argcount);
576
577         fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
578
579         STATS(jnicallXmethodnvokation();)
580
581         ret = asm_calljavafunction2int(methodID,
582                                                                    argcount,
583                                                                    argcount * sizeof(jni_callblock),
584                                                                    blk);
585
586         MFREE(blk, jni_callblock, argcount);
587
588         return ret;
589 }
590
591
592 /* callLongMethod **************************************************************
593
594    Core function for long class functions.
595
596 *******************************************************************************/
597
598 static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
599 {
600         s4             argcount;
601         jni_callblock *blk;
602         jlong          ret;
603
604         STATS(jniinvokation();)
605
606         if (methodID == 0) {
607                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
608                 return 0;
609         }
610
611         if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
612                    ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
613                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
614                 return 0;
615         }
616
617         if (obj && !builtin_instanceof(obj, methodID->class)) {
618                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
619                 return 0;
620         }
621
622         argcount = methodID->parseddesc->paramcount;
623
624         blk = MNEW(jni_callblock, argcount);
625
626         fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, TYPE_LNG);
627
628         STATS(jnicallXmethodnvokation();)
629
630         ret = asm_calljavafunction2long(methodID,
631                                                                         argcount,
632                                                                         argcount * sizeof(jni_callblock),
633                                                                         blk);
634
635         MFREE(blk, jni_callblock, argcount);
636
637         return ret;
638 }
639
640
641 /*core function for float class methods (float,double)*/
642 static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
643 {
644         int argcount = methodID->parseddesc->paramcount;
645         jni_callblock *blk;
646         jdouble ret;
647
648         STATS(jniinvokation();)
649
650         assert(0);
651
652         if (argcount > 3) {
653                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
654                 log_text("Too many arguments. CallObjectMethod does not support that");
655                 return 0;
656         }
657
658         blk = MNEW(jni_callblock, /*4 */ argcount+2);
659
660         fill_callblock_from_vargs(obj, methodID->parseddesc, blk, args, retType);
661
662         /*      printf("parameter: obj: %p",blk[0].item); */
663         STATS(jnicallXmethodnvokation();)
664         ret = asm_calljavafunction2double(methodID,
665                                                                           argcount + 1,
666                                                                           (argcount + 1) * sizeof(jni_callblock),
667                                                                           blk);
668
669         MFREE(blk, jni_callblock, argcount + 1);
670         /*      printf("(CallObjectMethodV)-->%p\n",ret); */
671
672         return ret;
673 }
674
675
676 static void cacao_jni_CallVoidMethod(jobject obj, jmethodID m, va_list ap)
677 {       
678         s4             paramcount;
679         jni_callblock *blk;
680
681         if (m == 0) {
682                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
683                 return;
684         }
685
686         if (!( ((m->flags & ACC_STATIC) && (obj == 0)) ||
687                 ((!(m->flags & ACC_STATIC)) && (obj != 0)) )) {
688                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
689                 return;
690         }
691
692         if (obj && !builtin_instanceof(obj, m->class)) {
693                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
694                 return;
695         }
696
697         paramcount = m->parseddesc->paramcount;
698
699         if (!(m->flags & ACC_STATIC))
700                 paramcount++;
701
702         blk = MNEW(jni_callblock, paramcount);
703
704         fill_callblock_from_vargs(obj, m->parseddesc, blk, ap, TYPE_VOID);
705
706         STATS(jnicallXmethodnvokation();)
707
708         (void) asm_calljavafunction2(m,
709                                                                  paramcount,
710                                                                  paramcount * sizeof(jni_callblock),
711                                                                  blk);
712
713         MFREE(blk, jni_callblock, paramcount);
714
715         return;
716 }
717
718
719 /* GetVersion ******************************************************************
720
721    Returns the major version number in the higher 16 bits and the
722    minor version number in the lower 16 bits.
723
724 *******************************************************************************/
725
726 jint GetVersion(JNIEnv *env)
727 {
728         STATS(jniinvokation();)
729
730         /* we support JNI 1.4 */
731
732         return JNI_VERSION_1_4;
733 }
734
735
736 /* Class Operations ***********************************************************/
737
738 /* DefineClass *****************************************************************
739
740    Loads a class from a buffer of raw class data. The buffer
741    containing the raw class data is not referenced by the VM after the
742    DefineClass call returns, and it may be discarded if desired.
743
744 *******************************************************************************/
745
746 jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
747                                    const jbyte *buf, jsize bufLen)
748 {
749         java_lang_ClassLoader *cl;
750         java_lang_String      *s;
751         java_bytearray        *ba;
752         jclass                 c;
753
754         STATS(jniinvokation();)
755
756         cl = (java_lang_ClassLoader *) loader;
757         s = javastring_new_char(name);
758         ba = (java_bytearray *) buf;
759
760         c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
761                                                                                                                   0, bufLen, NULL);
762
763         return c;
764 }
765
766
767 /* FindClass *******************************************************************
768
769    This function loads a locally-defined class. It searches the
770    directories and zip files specified by the CLASSPATH environment
771    variable for the class with the specified name.
772
773 *******************************************************************************/
774
775 jclass FindClass(JNIEnv *env, const char *name)
776 {
777         utf               *u;
778         classinfo         *c;
779         java_objectheader *cl;
780
781         STATS(jniinvokation();)
782
783         u = utf_new_char_classname((char *) name);
784
785         /* check stacktrace for classloader, if one found use it, otherwise use */
786         /* the system classloader */
787
788 #if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
789         /* these JITs support stacktraces, and so does the interpreter */
790
791         cl = cacao_currentClassLoader();
792 #else
793 # if defined(ENABLE_INTRP)
794         /* the interpreter supports stacktraces, even if the JIT does not */
795
796         if (opt_intrp)
797                 cl = cacao_currentClassLoader();
798         else
799 # endif
800                 cl = NULL;
801 #endif
802
803         if (!(c = load_class_from_classloader(u, cl)))
804                 return NULL;
805
806         if (!link_class(c))
807                 return NULL;
808
809         if (!use_class_as_object(c))
810                 return NULL;
811
812         return (jclass) NewLocalRef(env, (jobject) c);
813 }
814   
815
816 /* FromReflectedMethod *********************************************************
817
818    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
819    object to a method ID.
820   
821 *******************************************************************************/
822   
823 jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
824 {
825         methodinfo *mi;
826         classinfo  *c;
827         s4          slot;
828
829         STATS(jniinvokation();)
830
831         if (method == NULL)
832                 return NULL;
833         
834         if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
835                 java_lang_reflect_Method *rm;
836
837                 rm = (java_lang_reflect_Method *) method;
838                 c = (classinfo *) (rm->declaringClass);
839                 slot = rm->slot;
840
841         } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
842                 java_lang_reflect_Constructor *rc;
843
844                 rc = (java_lang_reflect_Constructor *) method;
845                 c = (classinfo *) (rc->clazz);
846                 slot = rc->slot;
847
848         } else
849                 return NULL;
850
851         if ((slot < 0) || (slot >= c->methodscount)) {
852                 /* this usually means a severe internal cacao error or somebody
853                    tempered around with the reflected method */
854                 log_text("error illegal slot for method in class(FromReflectedMethod)");
855                 assert(0);
856         }
857
858         mi = &(c->methods[slot]);
859
860         return mi;
861 }
862
863
864 /* GetSuperclass ***************************************************************
865
866    If clazz represents any class other than the class Object, then
867    this function returns the object that represents the superclass of
868    the class specified by clazz.
869
870 *******************************************************************************/
871  
872 jclass GetSuperclass(JNIEnv *env, jclass sub)
873 {
874         classinfo *c;
875         STATS(jniinvokation();)
876
877         c = ((classinfo *) sub)->super.cls;
878
879         if (!c)
880                 return NULL;
881
882         use_class_as_object(c);
883
884         return c;
885 }
886   
887  
888 /* IsAssignableFrom ************************************************************
889
890    Determines whether an object of sub can be safely cast to sup.
891
892 *******************************************************************************/
893
894 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
895 {
896         STATS(jniinvokation();)
897         return Java_java_lang_VMClass_isAssignableFrom(env,
898                                                                                                    NULL,
899                                                                                                    (java_lang_Class *) sup,
900                                                                                                    (java_lang_Class *) sub);
901 }
902
903
904 /***** converts a field ID derived from cls to a java.lang.reflect.Field object ***/
905
906 jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
907 {
908         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!!!");
909         STATS(jniinvokation();)
910         return NULL;
911 }
912
913
914 /* Throw ***********************************************************************
915
916    Causes a java.lang.Throwable object to be thrown.
917
918 *******************************************************************************/
919
920 jint Throw(JNIEnv *env, jthrowable obj)
921 {
922         *exceptionptr = (java_objectheader *) obj;
923         STATS(jniinvokation();)
924
925         return JNI_OK;
926 }
927
928
929 /* ThrowNew ********************************************************************
930
931    Constructs an exception object from the specified class with the
932    message specified by message and causes that exception to be
933    thrown.
934
935 *******************************************************************************/
936
937 jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
938 {
939         java_lang_Throwable *o;
940         java_lang_String    *s;
941         STATS(jniinvokation();)
942
943         s = (java_lang_String *) javastring_new_char(msg);
944
945         /* instantiate exception object */
946
947         o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
948                                                                                                                    s);
949
950         if (!o)
951                 return -1;
952
953         *exceptionptr = (java_objectheader *) o;
954
955         return 0;
956 }
957
958
959 /* ExceptionOccurred ***********************************************************
960
961    Determines if an exception is being thrown. The exception stays
962    being thrown until either the native code calls ExceptionClear(),
963    or the Java code handles the exception.
964
965 *******************************************************************************/
966
967 jthrowable ExceptionOccurred(JNIEnv *env)
968 {
969         java_objectheader *e;
970
971         STATS(jniinvokation();)
972
973         e = *exceptionptr;
974
975         return NewLocalRef(env, (jthrowable) e);
976 }
977
978
979 /* ExceptionDescribe ***********************************************************
980
981    Prints an exception and a backtrace of the stack to a system
982    error-reporting channel, such as stderr. This is a convenience
983    routine provided for debugging.
984
985 *******************************************************************************/
986
987 void ExceptionDescribe(JNIEnv *env)
988 {
989         java_objectheader *e;
990         methodinfo        *m;
991         STATS(jniinvokation();)
992
993         e = *exceptionptr;
994
995         if (e) {
996                 /* clear exception, because we are calling jit code again */
997
998                 *exceptionptr = NULL;
999
1000                 /* get printStackTrace method from exception class */
1001
1002                 m = class_resolveclassmethod(e->vftbl->class,
1003                                                                          utf_printStackTrace,
1004                                                                          utf_void__void,
1005                                                                          NULL,
1006                                                                          true);
1007
1008                 if (!m)
1009                         /* XXX what should we do? */
1010                         return;
1011
1012                 /* print the stacktrace */
1013
1014                 asm_calljavafunction(m, e, NULL, NULL, NULL);
1015         }
1016 }
1017
1018
1019 /* ExceptionClear **************************************************************
1020
1021    Clears any exception that is currently being thrown. If no
1022    exception is currently being thrown, this routine has no effect.
1023
1024 *******************************************************************************/
1025
1026 void ExceptionClear(JNIEnv *env)
1027 {
1028         STATS(jniinvokation();)
1029
1030         *exceptionptr = NULL;
1031 }
1032
1033
1034 /* FatalError ******************************************************************
1035
1036    Raises a fatal error and does not expect the VM to recover. This
1037    function does not return.
1038
1039 *******************************************************************************/
1040
1041 void FatalError(JNIEnv *env, const char *msg)
1042 {
1043         STATS(jniinvokation();)
1044
1045         throw_cacao_exception_exit(string_java_lang_InternalError, msg);
1046 }
1047
1048
1049 /* PushLocalFrame **************************************************************
1050
1051    Creates a new local reference frame, in which at least a given
1052    number of local references can be created.
1053
1054 *******************************************************************************/
1055
1056 jint PushLocalFrame(JNIEnv* env, jint capacity)
1057 {
1058         STATS(jniinvokation();)
1059
1060         log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
1061
1062         assert(0);
1063
1064         return 0;
1065 }
1066
1067 /* PopLocalFrame ***************************************************************
1068
1069    Pops off the current local reference frame, frees all the local
1070    references, and returns a local reference in the previous local
1071    reference frame for the given result object.
1072
1073 *******************************************************************************/
1074
1075 jobject PopLocalFrame(JNIEnv* env, jobject result)
1076 {
1077         STATS(jniinvokation();)
1078
1079         log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
1080
1081         assert(0);
1082
1083         /* add local reference and return the value */
1084
1085         return NewLocalRef(env, NULL);
1086 }
1087
1088
1089 /* DeleteLocalRef **************************************************************
1090
1091    Deletes the local reference pointed to by localRef.
1092
1093 *******************************************************************************/
1094
1095 void DeleteLocalRef(JNIEnv *env, jobject localRef)
1096 {
1097         java_objectheader *o;
1098         localref_table    *lrt;
1099         s4                 i;
1100
1101         STATS(jniinvokation();)
1102
1103         o = (java_objectheader *) localRef;
1104
1105         /* get local reference table (thread specific) */
1106
1107         lrt = LOCALREFTABLE;
1108
1109         /* remove the reference */
1110
1111         for (i = 0; i < lrt->capacity; i++) {
1112                 if (lrt->refs[i] == o) {
1113                         lrt->refs[i] = NULL;
1114                         lrt->used--;
1115
1116                         return;
1117                 }
1118         }
1119
1120         /* this should not happen */
1121
1122 /*      if (opt_checkjni) */
1123 /*      FatalError(env, "Bad global or local ref passed to JNI"); */
1124         log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
1125 }
1126
1127
1128 /* IsSameObject ****************************************************************
1129
1130    Tests whether two references refer to the same Java object.
1131
1132 *******************************************************************************/
1133
1134 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1135 {
1136         STATS(jniinvokation();)
1137
1138         if (ref1 == ref2)
1139                 return JNI_TRUE;
1140         else
1141                 return JNI_FALSE;
1142 }
1143
1144
1145 /* NewLocalRef *****************************************************************
1146
1147    Creates a new local reference that refers to the same object as ref.
1148
1149 *******************************************************************************/
1150
1151 jobject NewLocalRef(JNIEnv *env, jobject ref)
1152 {
1153         localref_table *lrt;
1154         s4              i;
1155
1156         STATS(jniinvokation();)
1157
1158         if (ref == NULL)
1159                 return NULL;
1160
1161         /* get local reference table (thread specific) */
1162
1163         lrt = LOCALREFTABLE;
1164
1165         /* check if we have space for the requested reference */
1166
1167         if (lrt->used == lrt->capacity)
1168                 throw_cacao_exception_exit(string_java_lang_InternalError,
1169                                                                    "Too many local references");
1170
1171         /* insert the reference */
1172
1173         for (i = 0; i < lrt->capacity; i++) {
1174                 if (lrt->refs[i] == NULL) {
1175                         lrt->refs[i] = (java_objectheader *) ref;
1176                         lrt->used++;
1177
1178                         return ref;
1179                 }
1180         }
1181
1182         /* should not happen, just to be sure */
1183
1184         assert(0);
1185
1186         /* keep compiler happy */
1187
1188         return NULL;
1189 }
1190
1191
1192 /* EnsureLocalCapacity *********************************************************
1193
1194    Ensures that at least a given number of local references can be
1195    created in the current thread
1196
1197 *******************************************************************************/
1198
1199 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1200 {
1201         localref_table *lrt;
1202
1203         STATS(jniinvokation();)
1204
1205         /* get local reference table (thread specific) */
1206
1207         lrt = LOCALREFTABLE;
1208
1209         /* check if capacity elements are available in the local references table */
1210
1211         if ((lrt->used + capacity) > lrt->capacity) {
1212                 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1213                 return -1;
1214         }
1215
1216         return 0;
1217 }
1218
1219
1220 /* AllocObject *****************************************************************
1221
1222    Allocates a new Java object without invoking any of the
1223    constructors for the object. Returns a reference to the object.
1224
1225 *******************************************************************************/
1226
1227 jobject AllocObject(JNIEnv *env, jclass clazz)
1228 {
1229         java_objectheader *o;
1230
1231         STATS(jniinvokation();)
1232
1233         if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1234                 *exceptionptr =
1235                         new_exception_utfmessage(string_java_lang_InstantiationException,
1236                                                                          clazz->name);
1237                 return NULL;
1238         }
1239                 
1240         o = builtin_new(clazz);
1241
1242         return NewLocalRef(env, o);
1243 }
1244
1245
1246 /* NewObject *******************************************************************
1247
1248    Programmers place all arguments that are to be passed to the
1249    constructor immediately following the methodID
1250    argument. NewObject() accepts these arguments and passes them to
1251    the Java method that the programmer wishes to invoke.
1252
1253 *******************************************************************************/
1254
1255 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1256 {
1257         java_objectheader *o;
1258         va_list            ap;
1259
1260         STATS(jniinvokation();)
1261
1262         /* create object */
1263
1264         o = builtin_new(clazz);
1265         
1266         if (!o)
1267                 return NULL;
1268
1269         /* call constructor */
1270
1271         va_start(ap, methodID);
1272         cacao_jni_CallVoidMethod(o, methodID, ap);
1273         va_end(ap);
1274
1275         return NewLocalRef(env, o);
1276 }
1277
1278
1279 /*********************************************************************************** 
1280
1281        Constructs a new Java object
1282        arguments that are to be passed to the constructor are placed in va_list args 
1283
1284 ***********************************************************************************/
1285
1286 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1287 {
1288         STATS(jniinvokation();)
1289
1290         log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1291
1292         return NewLocalRef(env, NULL);
1293 }
1294
1295
1296 /*********************************************************************************** 
1297
1298         Constructs a new Java object
1299         arguments that are to be passed to the constructor are placed in 
1300         args array of jvalues 
1301
1302 ***********************************************************************************/
1303
1304 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1305 {
1306         STATS(jniinvokation();)
1307
1308         log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1309
1310         return NewLocalRef(env, NULL);
1311 }
1312
1313
1314 /* GetObjectClass **************************************************************
1315
1316  Returns the class of an object.
1317
1318 *******************************************************************************/
1319
1320 jclass GetObjectClass(JNIEnv *env, jobject obj)
1321 {
1322         classinfo *c;
1323         STATS(jniinvokation();)
1324         
1325         if (!obj || !obj->vftbl)
1326                 return NULL;
1327
1328         c = obj->vftbl->class;
1329         use_class_as_object(c);
1330         return c;
1331 }
1332
1333
1334 /* IsInstanceOf ****************************************************************
1335
1336    Tests whether an object is an instance of a class.
1337
1338 *******************************************************************************/
1339
1340 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1341 {
1342         STATS(jniinvokation();)
1343
1344         return Java_java_lang_VMClass_isInstance(env,
1345                                                                                          NULL,
1346                                                                                          (java_lang_Class *) clazz,
1347                                                                                          (java_lang_Object *) obj);
1348 }
1349
1350
1351 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1352  
1353 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1354 {
1355         java_lang_reflect_Field *f;
1356         classinfo *c;
1357         jfieldID fid;   /* the JNI-fieldid of the wrapping object */
1358         STATS(jniinvokation();)
1359         /*log_text("JNI-Call: FromReflectedField");*/
1360
1361         f=(java_lang_reflect_Field *)field;
1362         if (f==0) return 0;
1363         c=(classinfo*)(f->declaringClass);
1364         if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1365                 /*this usually means a severe internal cacao error or somebody
1366                 tempered around with the reflected method*/
1367                 log_text("error illegal slot for field in class(FromReflectedField)");
1368                 assert(0);
1369         }
1370         fid=&(c->fields[f->slot]);
1371         return fid;
1372 }
1373
1374
1375 /**********************************************************************************
1376
1377         converts a method ID to a java.lang.reflect.Method or 
1378         java.lang.reflect.Constructor object
1379
1380 **********************************************************************************/
1381
1382 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1383 {
1384         log_text("JNI-Call: ToReflectedMethod");
1385         STATS(jniinvokation();)
1386
1387         return NULL;
1388 }
1389
1390
1391 /* GetMethodID *****************************************************************
1392
1393    returns the method ID for an instance method
1394
1395 *******************************************************************************/
1396
1397 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1398 {
1399         methodinfo *m;
1400
1401         STATS(jniinvokation();)
1402
1403         m = class_resolvemethod(clazz, 
1404                                                         utf_new_char((char *) name), 
1405                                                         utf_new_char((char *) sig));
1406
1407         if (!m || (m->flags & ACC_STATIC)) {
1408                 *exceptionptr =
1409                         new_exception_message(string_java_lang_NoSuchMethodError, name);
1410
1411                 return NULL;
1412         }
1413
1414         return m;
1415 }
1416
1417
1418 /******************** JNI-functions for calling instance methods ******************/
1419
1420 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1421 {
1422         java_objectheader* ret;
1423         va_list            vaargs;
1424
1425         STATS(jniinvokation();)
1426
1427         va_start(vaargs, methodID);
1428         ret = callObjectMethod(obj, methodID, vaargs);
1429         va_end(vaargs);
1430
1431         return NewLocalRef(env, ret);
1432 }
1433
1434
1435 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1436 {
1437         java_objectheader* ret;
1438
1439         STATS(jniinvokation();)
1440
1441         ret = callObjectMethod(obj, methodID, args);
1442
1443         return NewLocalRef(env, ret);
1444 }
1445
1446
1447 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1448 {
1449         STATS(jniinvokation();)
1450
1451         log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1452
1453         return NewLocalRef(env, NULL);
1454 }
1455
1456
1457
1458
1459 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1460 {
1461         jboolean ret;
1462         va_list vaargs;
1463         STATS(jniinvokation();)
1464
1465 /*      log_text("JNI-Call: CallBooleanMethod");*/
1466
1467         va_start(vaargs,methodID);
1468         ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1469         va_end(vaargs);
1470         return ret;
1471
1472 }
1473
1474 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1475 {
1476         STATS(jniinvokation();)
1477
1478         return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1479
1480 }
1481
1482 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1483 {
1484         STATS(jniinvokation();)
1485         log_text("JNI-Call: CallBooleanMethodA");
1486
1487         return 0;
1488 }
1489
1490 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1491 {
1492         jbyte ret;
1493         va_list vaargs;
1494         STATS(jniinvokation();)
1495
1496 /*      log_text("JNI-Call: CallVyteMethod");*/
1497
1498         va_start(vaargs,methodID);
1499         ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1500         va_end(vaargs);
1501         return ret;
1502
1503 }
1504
1505 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1506 {
1507 /*      log_text("JNI-Call: CallByteMethodV");*/
1508         STATS(jniinvokation();)
1509
1510         return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1511 }
1512
1513
1514 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1515 {
1516         log_text("JNI-Call: CallByteMethodA");
1517         STATS(jniinvokation();)
1518
1519         return 0;
1520 }
1521
1522
1523 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1524 {
1525         jchar ret;
1526         va_list vaargs;
1527         STATS(jniinvokation();)
1528
1529 /*      log_text("JNI-Call: CallCharMethod");*/
1530
1531         va_start(vaargs,methodID);
1532         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1533         va_end(vaargs);
1534
1535         return ret;
1536 }
1537
1538
1539 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1540 {
1541         STATS(jniinvokation();)
1542
1543 /*      log_text("JNI-Call: CallCharMethodV");*/
1544         return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1545 }
1546
1547
1548 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1549 {
1550         STATS(jniinvokation();)
1551
1552         log_text("JNI-Call: CallCharMethodA");
1553
1554         return 0;
1555 }
1556
1557
1558 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1559 {
1560         jshort ret;
1561         va_list vaargs;
1562         STATS(jniinvokation();)
1563
1564 /*      log_text("JNI-Call: CallShortMethod");*/
1565
1566         va_start(vaargs, methodID);
1567         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1568         va_end(vaargs);
1569
1570         return ret;
1571 }
1572
1573
1574 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1575 {
1576         STATS(jniinvokation();)
1577         return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1578 }
1579
1580
1581 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1582 {
1583         STATS(jniinvokation();)
1584         log_text("JNI-Call: CallShortMethodA");
1585
1586         return 0;
1587 }
1588
1589
1590
1591 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1592 {
1593         jint ret;
1594         va_list vaargs;
1595         STATS(jniinvokation();)
1596
1597         va_start(vaargs,methodID);
1598         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1599         va_end(vaargs);
1600
1601         return ret;
1602 }
1603
1604
1605 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1606 {
1607         STATS(jniinvokation();)
1608         return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1609 }
1610
1611
1612 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1613 {
1614         STATS(jniinvokation();)
1615         log_text("JNI-Call: CallIntMethodA");
1616
1617         return 0;
1618 }
1619
1620
1621
1622 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1623 {
1624         jlong ret;
1625         va_list vaargs;
1626         STATS(jniinvokation();)
1627         
1628         va_start(vaargs,methodID);
1629         ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1630         va_end(vaargs);
1631
1632         return ret;
1633 }
1634
1635
1636 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1637 {
1638         STATS(jniinvokation();)
1639         return  callLongMethod(obj,get_virtual(obj, methodID),args);
1640 }
1641
1642
1643 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1644 {
1645         STATS(jniinvokation();)
1646         log_text("JNI-Call: CallLongMethodA");
1647
1648         return 0;
1649 }
1650
1651
1652
1653 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1654 {
1655         jfloat ret;
1656         va_list vaargs;
1657
1658         STATS(jniinvokation();)
1659 /*      log_text("JNI-Call: CallFloatMethod");*/
1660
1661         va_start(vaargs,methodID);
1662         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1663         va_end(vaargs);
1664
1665         return ret;
1666 }
1667
1668
1669 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1670 {
1671         STATS(jniinvokation();)
1672         log_text("JNI-Call: CallFloatMethodV");
1673         return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1674 }
1675
1676
1677 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1678 {
1679         STATS(jniinvokation();)
1680         log_text("JNI-Call: CallFloatMethodA");
1681
1682         return 0;
1683 }
1684
1685
1686
1687 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1688 {
1689         jdouble ret;
1690         va_list vaargs;
1691         STATS(jniinvokation();)
1692
1693 /*      log_text("JNI-Call: CallDoubleMethod");*/
1694
1695         va_start(vaargs,methodID);
1696         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1697         va_end(vaargs);
1698
1699         return ret;
1700 }
1701
1702
1703 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1704 {
1705         STATS(jniinvokation();)
1706         log_text("JNI-Call: CallDoubleMethodV");
1707         return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1708 }
1709
1710
1711 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1712 {
1713         STATS(jniinvokation();)
1714         log_text("JNI-Call: CallDoubleMethodA");
1715         return 0;
1716 }
1717
1718
1719
1720 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1721 {
1722         va_list vaargs;
1723         STATS(jniinvokation();)
1724
1725         va_start(vaargs,methodID);
1726         (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1727         va_end(vaargs);
1728 }
1729
1730
1731 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1732 {
1733         log_text("JNI-Call: CallVoidMethodV");
1734         STATS(jniinvokation();)
1735         (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1736 }
1737
1738
1739 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1740 {
1741         STATS(jniinvokation();)
1742         log_text("JNI-Call: CallVoidMethodA");
1743 }
1744
1745
1746
1747 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1748 {
1749         STATS(jniinvokation();)
1750
1751         log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1752
1753         return NewLocalRef(env, NULL);
1754 }
1755
1756
1757 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1758 {
1759         STATS(jniinvokation();)
1760
1761         log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1762
1763         return NewLocalRef(env, NULL);
1764 }
1765
1766
1767 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1768 {
1769         STATS(jniinvokation();)
1770
1771         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1772
1773         return NewLocalRef(env, NULL);
1774 }
1775
1776
1777
1778 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1779 {
1780         jboolean ret;
1781         va_list vaargs;
1782         STATS(jniinvokation();)
1783
1784 /*      log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1785
1786         va_start(vaargs,methodID);
1787         ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1788         va_end(vaargs);
1789         return ret;
1790
1791 }
1792
1793
1794 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1795 {
1796         STATS(jniinvokation();)
1797 /*      log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1798         return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1799 }
1800
1801
1802 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1803 {
1804         STATS(jniinvokation();)
1805         log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1806
1807         return 0;
1808 }
1809
1810
1811
1812 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1813 {
1814         jbyte ret;
1815         va_list vaargs;
1816
1817         STATS(jniinvokation();)
1818 /*      log_text("JNI-Call: CallNonvirutalByteMethod");*/
1819
1820         va_start(vaargs,methodID);
1821         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1822         va_end(vaargs);
1823         return ret;
1824 }
1825
1826
1827 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1828 {
1829         STATS(jniinvokation();)
1830         /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1831         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1832
1833 }
1834
1835
1836 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1837 {
1838         STATS(jniinvokation();)
1839         log_text("JNI-Call: CallNonvirtualByteMethodA");
1840
1841         return 0;
1842 }
1843
1844
1845
1846 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1847 {
1848         jchar ret;
1849         va_list vaargs;
1850
1851         STATS(jniinvokation();)
1852 /*      log_text("JNI-Call: CallNonVirtualCharMethod");*/
1853
1854         va_start(vaargs,methodID);
1855         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1856         va_end(vaargs);
1857         return ret;
1858 }
1859
1860
1861 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1862 {
1863         STATS(jniinvokation();)
1864         /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1865         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1866 }
1867
1868
1869 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1870 {
1871         STATS(jniinvokation();)
1872         log_text("JNI-Call: CallNonvirtualCharMethodA");
1873
1874         return 0;
1875 }
1876
1877
1878
1879 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1880 {
1881         jshort ret;
1882         va_list vaargs;
1883         STATS(jniinvokation();)
1884
1885         /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1886
1887         va_start(vaargs,methodID);
1888         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1889         va_end(vaargs);
1890         return ret;
1891 }
1892
1893
1894 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1895 {
1896         STATS(jniinvokation();)
1897         /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1898         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1899 }
1900
1901
1902 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1903 {
1904         STATS(jniinvokation();)
1905         log_text("JNI-Call: CallNonvirtualShortMethodA");
1906
1907         return 0;
1908 }
1909
1910
1911
1912 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1913 {
1914
1915         jint ret;
1916         va_list vaargs;
1917         STATS(jniinvokation();)
1918
1919         /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1920
1921         va_start(vaargs,methodID);
1922         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1923         va_end(vaargs);
1924         return ret;
1925 }
1926
1927
1928 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1929 {
1930         STATS(jniinvokation();)
1931         /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1932         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1933 }
1934
1935
1936 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1937 {
1938         STATS(jniinvokation();)
1939         log_text("JNI-Call: CallNonvirtualIntMethodA");
1940
1941         return 0;
1942 }
1943
1944
1945
1946 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1947 {
1948         STATS(jniinvokation();)
1949         log_text("JNI-Call: CallNonvirtualLongMethod");
1950
1951         return 0;
1952 }
1953
1954
1955 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1956 {
1957         STATS(jniinvokation();)
1958         log_text("JNI-Call: CallNonvirtualLongMethodV");
1959
1960         return 0;
1961 }
1962
1963
1964 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1965 {
1966         STATS(jniinvokation();)
1967         log_text("JNI-Call: CallNonvirtualLongMethodA");
1968
1969         return 0;
1970 }
1971
1972
1973
1974 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1975 {
1976         jfloat ret;
1977         va_list vaargs;
1978         STATS(jniinvokation();)
1979
1980         /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1981
1982
1983         va_start(vaargs,methodID);
1984         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1985         va_end(vaargs);
1986         return ret;
1987
1988 }
1989
1990
1991 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1992 {
1993         STATS(jniinvokation();)
1994         log_text("JNI-Call: CallNonvirtualFloatMethodV");
1995         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1996 }
1997
1998
1999 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2000 {
2001         STATS(jniinvokation();)
2002         log_text("JNI-Call: CallNonvirtualFloatMethodA");
2003
2004         return 0;
2005 }
2006
2007
2008
2009 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2010 {
2011         jdouble ret;
2012         va_list vaargs;
2013         STATS(jniinvokation();)
2014         log_text("JNI-Call: CallNonvirtualDoubleMethod");
2015
2016         va_start(vaargs,methodID);
2017         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2018         va_end(vaargs);
2019         return ret;
2020
2021 }
2022
2023
2024 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2025 {
2026         STATS(jniinvokation();)
2027 /*      log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2028         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2029 }
2030
2031
2032 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2033 {
2034         STATS(jniinvokation();)
2035         log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2036
2037         return 0;
2038 }
2039
2040
2041
2042 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2043 {
2044         va_list vaargs;
2045         STATS(jniinvokation();)
2046
2047 /*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2048
2049         va_start(vaargs,methodID);
2050         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2051         va_end(vaargs);
2052
2053 }
2054
2055
2056 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2057 {
2058 /*      log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2059         STATS(jniinvokation();)
2060
2061         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2062
2063 }
2064
2065
2066 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2067 {
2068         STATS(jniinvokation();)
2069         log_text("JNI-Call: CallNonvirtualVoidMethodA");
2070 }
2071
2072 /************************* JNI-functions for accessing fields ************************/
2073
2074 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) 
2075 {
2076         jfieldID f;
2077
2078         STATS(jniinvokation();)
2079
2080         f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig)); 
2081         
2082         if (!f)
2083                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2084
2085         return f;
2086 }
2087
2088 /*************************** retrieve fieldid, abort on error ************************/
2089
2090 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
2091 {
2092     jfieldID id = GetFieldID(env, clazz, name, sig);
2093         STATS(jniinvokation();)
2094
2095     if (!id) {
2096        log_text("class:");
2097        utf_display(clazz->name);
2098        log_text("\nfield:");
2099        log_text(name);
2100        log_text("sig:");
2101        log_text(sig);
2102
2103        log_text("setfield_critical failed");
2104            assert(0);
2105     }
2106     return id;
2107 }
2108
2109 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2110 {
2111         java_objectheader *o;
2112
2113         STATS(jniinvokation();)
2114
2115         o = getField(obj, java_objectheader*, fieldID);
2116
2117         return NewLocalRef(env, o);
2118 }
2119
2120 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2121 {
2122         STATS(jniinvokation();)
2123         return getField(obj,jboolean,fieldID);
2124 }
2125
2126
2127 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2128 {
2129         STATS(jniinvokation();)
2130         return getField(obj,jbyte,fieldID);
2131 }
2132
2133
2134 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2135 {
2136         STATS(jniinvokation();)
2137         return getField(obj,jchar,fieldID);
2138 }
2139
2140
2141 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2142 {
2143         STATS(jniinvokation();)
2144         return getField(obj,jshort,fieldID);
2145 }
2146
2147
2148 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2149 {
2150         STATS(jniinvokation();)
2151         return getField(obj,jint,fieldID);
2152 }
2153
2154
2155 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2156 {
2157         STATS(jniinvokation();)
2158         return getField(obj,jlong,fieldID);
2159 }
2160
2161
2162 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2163 {
2164         STATS(jniinvokation();)
2165         return getField(obj,jfloat,fieldID);
2166 }
2167
2168
2169 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2170 {
2171         STATS(jniinvokation();)
2172         return getField(obj,jdouble,fieldID);
2173 }
2174
2175 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2176 {
2177         STATS(jniinvokation();)
2178         setField(obj,jobject,fieldID,val);
2179 }
2180
2181
2182 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2183 {
2184         STATS(jniinvokation();)
2185         setField(obj,jboolean,fieldID,val);
2186 }
2187
2188
2189 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2190 {
2191         STATS(jniinvokation();)
2192         setField(obj,jbyte,fieldID,val);
2193 }
2194
2195
2196 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2197 {
2198         STATS(jniinvokation();)
2199         setField(obj,jchar,fieldID,val);
2200 }
2201
2202
2203 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2204 {
2205         STATS(jniinvokation();)
2206         setField(obj,jshort,fieldID,val);
2207 }
2208
2209
2210 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2211 {
2212         STATS(jniinvokation();)
2213         setField(obj,jint,fieldID,val);
2214 }
2215
2216
2217 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2218 {
2219         STATS(jniinvokation();)
2220         setField(obj,jlong,fieldID,val);
2221 }
2222
2223
2224 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2225 {
2226         STATS(jniinvokation();)
2227         setField(obj,jfloat,fieldID,val);
2228 }
2229
2230
2231 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2232 {
2233         STATS(jniinvokation();)
2234         setField(obj,jdouble,fieldID,val);
2235 }
2236
2237
2238 /**************** JNI-functions for calling static methods **********************/ 
2239
2240 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2241 {
2242         jmethodID m;
2243         STATS(jniinvokation();)
2244
2245         m = class_resolvemethod(clazz,
2246                                                         utf_new_char((char *) name),
2247                                                         utf_new_char((char *) sig));
2248
2249         if (!m || !(m->flags & ACC_STATIC)) {
2250                 *exceptionptr =
2251                         new_exception_message(string_java_lang_NoSuchMethodError, name);
2252
2253                 return NULL;
2254         }
2255
2256         return m;
2257 }
2258
2259
2260 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2261 {
2262         java_objectheader *ret;
2263         va_list            vaargs;
2264
2265         STATS(jniinvokation();)
2266
2267         va_start(vaargs, methodID);
2268         ret = callObjectMethod(0, methodID, vaargs);
2269         va_end(vaargs);
2270
2271         return NewLocalRef(env, ret);
2272 }
2273
2274
2275 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2276 {
2277         java_objectheader *ret;
2278
2279         STATS(jniinvokation();)
2280         
2281         ret = callObjectMethod(0, methodID, args);
2282
2283         return NewLocalRef(env, ret);
2284 }
2285
2286
2287 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2288 {
2289         STATS(jniinvokation();)
2290
2291         log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2292
2293         return NewLocalRef(env, NULL);
2294 }
2295
2296
2297 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2298 {
2299         jboolean ret;
2300         va_list vaargs;
2301         STATS(jniinvokation();)
2302
2303         va_start(vaargs, methodID);
2304         ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2305         va_end(vaargs);
2306
2307         return ret;
2308 }
2309
2310
2311 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2312 {
2313         STATS(jniinvokation();)
2314         return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2315 }
2316
2317
2318 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2319 {
2320         STATS(jniinvokation();)
2321         log_text("JNI-Call: CallStaticBooleanMethodA");
2322
2323         return 0;
2324 }
2325
2326
2327 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2328 {
2329         jbyte ret;
2330         va_list vaargs;
2331         STATS(jniinvokation();)
2332
2333         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2334
2335         va_start(vaargs, methodID);
2336         ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2337         va_end(vaargs);
2338
2339         return ret;
2340 }
2341
2342
2343 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2344 {
2345         STATS(jniinvokation();)
2346         return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2347 }
2348
2349
2350 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2351 {
2352         STATS(jniinvokation();)
2353         log_text("JNI-Call: CallStaticByteMethodA");
2354
2355         return 0;
2356 }
2357
2358
2359 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2360 {
2361         jchar ret;
2362         va_list vaargs;
2363         STATS(jniinvokation();)
2364
2365         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2366
2367         va_start(vaargs, methodID);
2368         ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2369         va_end(vaargs);
2370
2371         return ret;
2372 }
2373
2374
2375 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2376 {
2377         STATS(jniinvokation();)
2378         return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2379 }
2380
2381
2382 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2383 {
2384         STATS(jniinvokation();)
2385         log_text("JNI-Call: CallStaticCharMethodA");
2386
2387         return 0;
2388 }
2389
2390
2391
2392 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2393 {
2394         jshort ret;
2395         va_list vaargs;
2396         STATS(jniinvokation();)
2397
2398         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2399
2400         va_start(vaargs, methodID);
2401         ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2402         va_end(vaargs);
2403
2404         return ret;
2405 }
2406
2407
2408 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2409 {
2410         STATS(jniinvokation();)
2411         /*log_text("JNI-Call: CallStaticShortMethodV");*/
2412         return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2413 }
2414
2415
2416 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2417 {
2418         STATS(jniinvokation();)
2419         log_text("JNI-Call: CallStaticShortMethodA");
2420
2421         return 0;
2422 }
2423
2424
2425
2426 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2427 {
2428         jint ret;
2429         va_list vaargs;
2430         STATS(jniinvokation();)
2431
2432         /*      log_text("JNI-Call: CallStaticIntMethod");*/
2433
2434         va_start(vaargs, methodID);
2435         ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2436         va_end(vaargs);
2437
2438         return ret;
2439 }
2440
2441
2442 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2443 {
2444         STATS(jniinvokation();)
2445         log_text("JNI-Call: CallStaticIntMethodV");
2446
2447         return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2448 }
2449
2450
2451 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2452 {
2453         STATS(jniinvokation();)
2454         log_text("JNI-Call: CallStaticIntMethodA");
2455
2456         return 0;
2457 }
2458
2459
2460
2461 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2462 {
2463         jlong ret;
2464         va_list vaargs;
2465         STATS(jniinvokation();)
2466
2467         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2468
2469         va_start(vaargs, methodID);
2470         ret = callLongMethod(0, methodID, vaargs);
2471         va_end(vaargs);
2472
2473         return ret;
2474 }
2475
2476
2477 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2478                                                         va_list args)
2479 {
2480         STATS(jniinvokation();)
2481         
2482         return callLongMethod(0, methodID, args);
2483 }
2484
2485
2486 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2487 {
2488         STATS(jniinvokation();)
2489
2490         log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!!!");
2491
2492         return 0;
2493 }
2494
2495
2496
2497 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2498 {
2499         jfloat ret;
2500         va_list vaargs;
2501         STATS(jniinvokation();)
2502
2503         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2504
2505         va_start(vaargs, methodID);
2506         ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2507         va_end(vaargs);
2508
2509         return ret;
2510 }
2511
2512
2513 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2514 {
2515         STATS(jniinvokation();)
2516
2517         return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2518
2519 }
2520
2521
2522 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2523 {
2524         STATS(jniinvokation();)
2525         log_text("JNI-Call: CallStaticFloatMethodA");
2526
2527         return 0;
2528 }
2529
2530
2531
2532 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2533 {
2534         jdouble ret;
2535         va_list vaargs;
2536         STATS(jniinvokation();)
2537
2538         /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
2539
2540         va_start(vaargs,methodID);
2541         ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2542         va_end(vaargs);
2543
2544         return ret;
2545 }
2546
2547
2548 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2549 {
2550         STATS(jniinvokation();)
2551         log_text("JNI-Call: CallStaticDoubleMethodV");
2552
2553         return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2554 }
2555
2556
2557 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2558 {
2559         STATS(jniinvokation();)
2560         log_text("JNI-Call: CallStaticDoubleMethodA");
2561
2562         return 0;
2563 }
2564
2565
2566 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2567 {
2568         va_list vaargs;
2569         STATS(jniinvokation();)
2570
2571         va_start(vaargs, methodID);
2572         (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2573         va_end(vaargs);
2574 }
2575
2576
2577 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2578 {
2579         log_text("JNI-Call: CallStaticVoidMethodV");
2580         STATS(jniinvokation();)
2581         (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2582 }
2583
2584
2585 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2586 {
2587         STATS(jniinvokation();)
2588         log_text("JNI-Call: CallStaticVoidMethodA");
2589 }
2590
2591
2592 /* Accessing Static Fields ****************************************************/
2593
2594 /* GetStaticFieldID ************************************************************
2595
2596    Returns the field ID for a static field of a class. The field is
2597    specified by its name and signature. The GetStatic<type>Field and
2598    SetStatic<type>Field families of accessor functions use field IDs
2599    to retrieve static fields.
2600
2601 *******************************************************************************/
2602
2603 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2604 {
2605         jfieldID f;
2606         STATS(jniinvokation();)
2607
2608         f = class_findfield(clazz,
2609                                                 utf_new_char((char *) name),
2610                                                 utf_new_char((char *) sig));
2611         
2612         if (!f)
2613                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2614
2615         return f;
2616 }
2617
2618
2619 /* GetStatic<type>Field ********************************************************
2620
2621    This family of accessor routines returns the value of a static
2622    field of an object.
2623
2624 *******************************************************************************/
2625
2626 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2627 {
2628         STATS(jniinvokation();)
2629
2630         if (!clazz->initialized)
2631                 if (!initialize_class(clazz))
2632                         return NULL;
2633
2634         return NewLocalRef(env, fieldID->value.a);
2635 }
2636
2637
2638 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2639 {
2640         STATS(jniinvokation();)
2641
2642         if (!clazz->initialized)
2643                 if (!initialize_class(clazz))
2644                         return false;
2645
2646         return fieldID->value.i;       
2647 }
2648
2649
2650 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2651 {
2652         STATS(jniinvokation();)
2653
2654         if (!clazz->initialized)
2655                 if (!initialize_class(clazz))
2656                         return 0;
2657
2658         return fieldID->value.i;       
2659 }
2660
2661
2662 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2663 {
2664         STATS(jniinvokation();)
2665
2666         if (!clazz->initialized)
2667                 if (!initialize_class(clazz))
2668                         return 0;
2669
2670         return fieldID->value.i;       
2671 }
2672
2673
2674 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2675 {
2676         STATS(jniinvokation();)
2677
2678         if (!clazz->initialized)
2679                 if (!initialize_class(clazz))
2680                         return 0;
2681
2682         return fieldID->value.i;       
2683 }
2684
2685
2686 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2687 {
2688         STATS(jniinvokation();)
2689
2690         if (!clazz->initialized)
2691                 if (!initialize_class(clazz))
2692                         return 0;
2693
2694         return fieldID->value.i;       
2695 }
2696
2697
2698 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2699 {
2700         STATS(jniinvokation();)
2701
2702         if (!clazz->initialized)
2703                 if (!initialize_class(clazz))
2704                         return 0;
2705
2706         return fieldID->value.l;
2707 }
2708
2709
2710 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2711 {
2712         STATS(jniinvokation();)
2713
2714         if (!clazz->initialized)
2715                 if (!initialize_class(clazz))
2716                         return 0.0;
2717
2718         return fieldID->value.f;
2719 }
2720
2721
2722 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2723 {
2724         STATS(jniinvokation();)
2725
2726         if (!clazz->initialized)
2727                 if (!initialize_class(clazz))
2728                         return 0.0;
2729
2730         return fieldID->value.d;
2731 }
2732
2733
2734 /*  SetStatic<type>Field *******************************************************
2735
2736         This family of accessor routines sets the value of a static field
2737         of an object.
2738
2739 *******************************************************************************/
2740
2741 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2742 {
2743         STATS(jniinvokation();)
2744
2745         if (!clazz->initialized)
2746                 if (!initialize_class(clazz))
2747                         return;
2748
2749         fieldID->value.a = value;
2750 }
2751
2752
2753 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2754 {
2755         STATS(jniinvokation();)
2756
2757         if (!clazz->initialized)
2758                 if (!initialize_class(clazz))
2759                         return;
2760
2761         fieldID->value.i = value;
2762 }
2763
2764
2765 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2766 {
2767         STATS(jniinvokation();)
2768
2769         if (!clazz->initialized)
2770                 if (!initialize_class(clazz))
2771                         return;
2772
2773         fieldID->value.i = value;
2774 }
2775
2776
2777 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2778 {
2779         STATS(jniinvokation();)
2780
2781         if (!clazz->initialized)
2782                 if (!initialize_class(clazz))
2783                         return;
2784
2785         fieldID->value.i = value;
2786 }
2787
2788
2789 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2790 {
2791         STATS(jniinvokation();)
2792
2793         if (!clazz->initialized)
2794                 if (!initialize_class(clazz))
2795                         return;
2796
2797         fieldID->value.i = value;
2798 }
2799
2800
2801 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2802 {
2803         STATS(jniinvokation();)
2804
2805         if (!clazz->initialized)
2806                 if (!initialize_class(clazz))
2807                         return;
2808
2809         fieldID->value.i = value;
2810 }
2811
2812
2813 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2814 {
2815         STATS(jniinvokation();)
2816
2817         if (!clazz->initialized)
2818                 if (!initialize_class(clazz))
2819                         return;
2820
2821         fieldID->value.l = value;
2822 }
2823
2824
2825 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2826 {
2827         STATS(jniinvokation();)
2828
2829         if (!clazz->initialized)
2830                 if (!initialize_class(clazz))
2831                         return;
2832
2833         fieldID->value.f = value;
2834 }
2835
2836
2837 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2838 {
2839         STATS(jniinvokation();)
2840
2841         if (!clazz->initialized)
2842                 if (!initialize_class(clazz))
2843                         return;
2844
2845         fieldID->value.d = value;
2846 }
2847
2848
2849 /* String Operations **********************************************************/
2850
2851 /* NewString *******************************************************************
2852
2853    Create new java.lang.String object from an array of Unicode
2854    characters.
2855
2856 *******************************************************************************/
2857
2858 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2859 {
2860         java_lang_String *s;
2861         java_chararray   *a;
2862         u4                i;
2863
2864         STATS(jniinvokation();)
2865         
2866         s = (java_lang_String *) builtin_new(class_java_lang_String);
2867         a = builtin_newarray_char(len);
2868
2869         /* javastring or characterarray could not be created */
2870         if (!a || !s)
2871                 return NULL;
2872
2873         /* copy text */
2874         for (i = 0; i < len; i++)
2875                 a->data[i] = buf[i];
2876
2877         s->value = a;
2878         s->offset = 0;
2879         s->count = len;
2880
2881         return (jstring) NewLocalRef(env, (jobject) s);
2882 }
2883
2884
2885 static jchar emptyStringJ[]={0,0};
2886
2887 /* GetStringLength *************************************************************
2888
2889    Returns the length (the count of Unicode characters) of a Java
2890    string.
2891
2892 *******************************************************************************/
2893
2894 jsize GetStringLength(JNIEnv *env, jstring str)
2895 {
2896         return ((java_lang_String *) str)->count;
2897 }
2898
2899
2900 /********************  convertes javastring to u2-array ****************************/
2901         
2902 u2 *javastring_tou2(jstring so) 
2903 {
2904         java_lang_String *s;
2905         java_chararray   *a;
2906         u2               *stringbuffer;
2907         u4                i;
2908
2909         STATS(jniinvokation();)
2910         
2911         s = (java_lang_String *) so;
2912
2913         if (!s)
2914                 return NULL;
2915
2916         a = s->value;
2917
2918         if (!a)
2919                 return NULL;
2920
2921         /* allocate memory */
2922
2923         stringbuffer = MNEW(u2, s->count + 1);
2924
2925         /* copy text */
2926
2927         for (i = 0; i < s->count; i++)
2928                 stringbuffer[i] = a->data[s->offset + i];
2929         
2930         /* terminate string */
2931
2932         stringbuffer[i] = '\0';
2933
2934         return stringbuffer;
2935 }
2936
2937
2938 /* GetStringChars **************************************************************
2939
2940    Returns a pointer to the array of Unicode characters of the
2941    string. This pointer is valid until ReleaseStringchars() is called.
2942
2943 *******************************************************************************/
2944
2945 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2946 {       
2947         jchar *jc;
2948
2949         STATS(jniinvokation();)
2950
2951         jc = javastring_tou2(str);
2952
2953         if (jc) {
2954                 if (isCopy)
2955                         *isCopy = JNI_TRUE;
2956
2957                 return jc;
2958         }
2959
2960         if (isCopy)
2961                 *isCopy = JNI_TRUE;
2962
2963         return emptyStringJ;
2964 }
2965
2966
2967 /* ReleaseStringChars **********************************************************
2968
2969    Informs the VM that the native code no longer needs access to
2970    chars. The chars argument is a pointer obtained from string using
2971    GetStringChars().
2972
2973 *******************************************************************************/
2974
2975 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2976 {
2977         STATS(jniinvokation();)
2978
2979         if (chars == emptyStringJ)
2980                 return;
2981
2982         MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2983 }
2984
2985
2986 /* NewStringUTF ****************************************************************
2987
2988    Constructs a new java.lang.String object from an array of UTF-8 characters.
2989
2990 *******************************************************************************/
2991
2992 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2993 {
2994         java_lang_String *s;
2995
2996         STATS(jniinvokation();)
2997
2998         s = javastring_new(utf_new_char(bytes));
2999
3000     return (jstring) NewLocalRef(env, (jobject) s);
3001 }
3002
3003
3004 /****************** returns the utf8 length in bytes of a string *******************/
3005
3006 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3007 {   
3008     java_lang_String *s = (java_lang_String*) string;
3009         STATS(jniinvokation();)
3010
3011     return (jsize) u2_utflength(s->value->data, s->count); 
3012 }
3013
3014
3015 /* GetStringUTFChars ***********************************************************
3016
3017    Returns a pointer to an array of UTF-8 characters of the
3018    string. This array is valid until it is released by
3019    ReleaseStringUTFChars().
3020
3021 *******************************************************************************/
3022
3023 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3024 {
3025         utf *u;
3026         STATS(jniinvokation();)
3027
3028         if (!string)
3029                 return "";
3030
3031         if (isCopy)
3032                 *isCopy = JNI_TRUE;
3033         
3034         u = javastring_toutf((java_lang_String *) string, false);
3035
3036         if (u)
3037                 return u->text;
3038
3039         return "";
3040 }
3041
3042
3043 /* ReleaseStringUTFChars *******************************************************
3044
3045    Informs the VM that the native code no longer needs access to
3046    utf. The utf argument is a pointer derived from string using
3047    GetStringUTFChars().
3048
3049 *******************************************************************************/
3050
3051 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3052 {
3053         STATS(jniinvokation();)
3054
3055     /* XXX we don't release utf chars right now, perhaps that should be done 
3056            later. Since there is always one reference the garbage collector will
3057            never get them */
3058 }
3059
3060
3061 /* Array Operations ***********************************************************/
3062
3063 /* GetArrayLength **************************************************************
3064
3065    Returns the number of elements in the array.
3066
3067 *******************************************************************************/
3068
3069 jsize GetArrayLength(JNIEnv *env, jarray array)
3070 {
3071         STATS(jniinvokation();)
3072
3073         return array->size;
3074 }
3075
3076
3077 /* NewObjectArray **************************************************************
3078
3079    Constructs a new array holding objects in class elementClass. All
3080    elements are initially set to initialElement.
3081
3082 *******************************************************************************/
3083
3084 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3085 {
3086         java_objectarray *oa;
3087         s4                i;
3088
3089         STATS(jniinvokation();)
3090
3091         if (length < 0) {
3092                 *exceptionptr = new_negativearraysizeexception();
3093                 return NULL;
3094         }
3095
3096     oa = builtin_anewarray(length, elementClass);
3097
3098         if (!oa)
3099                 return NULL;
3100
3101         /* set all elements to initialElement */
3102
3103         for (i = 0; i < length; i++)
3104                 oa->data[i] = initialElement;
3105
3106         return (jobjectArray) NewLocalRef(env, (jobject) oa);
3107 }
3108
3109
3110 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3111 {
3112     jobject o;
3113
3114         STATS(jniinvokation();)
3115
3116         if (index >= array->header.size) {
3117                 *exceptionptr =
3118                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3119                 return NULL;
3120         }
3121
3122         o = array->data[index];
3123     
3124     return NewLocalRef(env, o);
3125 }
3126
3127
3128 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3129 {
3130         STATS(jniinvokation();)
3131     if (index >= array->header.size)
3132                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3133
3134     else {
3135                 /* check if the class of value is a subclass of the element class of the array */
3136                 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3137                         *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3138
3139                 else
3140                         array->data[index] = val;
3141     }
3142 }
3143
3144
3145 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3146 {
3147         java_booleanarray *ba;
3148
3149         STATS(jniinvokation();)
3150
3151         if (len < 0) {
3152                 *exceptionptr = new_negativearraysizeexception();
3153                 return NULL;
3154         }
3155
3156         ba = builtin_newarray_boolean(len);
3157
3158         return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3159 }
3160
3161
3162 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3163 {
3164         java_bytearray *ba;
3165
3166         STATS(jniinvokation();)
3167
3168         if (len < 0) {
3169                 *exceptionptr = new_negativearraysizeexception();
3170                 return NULL;
3171         }
3172
3173         ba = builtin_newarray_byte(len);
3174
3175         return (jbyteArray) NewLocalRef(env, (jobject) ba);
3176 }
3177
3178
3179 jcharArray NewCharArray(JNIEnv *env, jsize len)
3180 {
3181         java_chararray *ca;
3182
3183         STATS(jniinvokation();)
3184
3185         if (len < 0) {
3186                 *exceptionptr = new_negativearraysizeexception();
3187                 return NULL;
3188         }
3189
3190         ca = builtin_newarray_char(len);
3191
3192         return (jcharArray) NewLocalRef(env, (jobject) ca);
3193 }
3194
3195
3196 jshortArray NewShortArray(JNIEnv *env, jsize len)
3197 {
3198         java_shortarray *sa;
3199
3200         STATS(jniinvokation();)
3201
3202         if (len < 0) {
3203                 *exceptionptr = new_negativearraysizeexception();
3204                 return NULL;
3205         }
3206
3207         sa = builtin_newarray_short(len);
3208
3209         return (jshortArray) NewLocalRef(env, (jobject) sa);
3210 }
3211
3212
3213 jintArray NewIntArray(JNIEnv *env, jsize len)
3214 {
3215         java_intarray *ia;
3216
3217         STATS(jniinvokation();)
3218
3219         if (len < 0) {
3220                 *exceptionptr = new_negativearraysizeexception();
3221                 return NULL;
3222         }
3223
3224         ia = builtin_newarray_int(len);
3225
3226         return (jintArray) NewLocalRef(env, (jobject) ia);
3227 }
3228
3229
3230 jlongArray NewLongArray(JNIEnv *env, jsize len)
3231 {
3232         java_longarray *la;
3233
3234         STATS(jniinvokation();)
3235
3236         if (len < 0) {
3237                 *exceptionptr = new_negativearraysizeexception();
3238                 return NULL;
3239         }
3240
3241         la = builtin_newarray_long(len);
3242
3243         return (jlongArray) NewLocalRef(env, (jobject) la);
3244 }
3245
3246
3247 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3248 {
3249         java_floatarray *fa;
3250
3251         STATS(jniinvokation();)
3252
3253         if (len < 0) {
3254                 *exceptionptr = new_negativearraysizeexception();
3255                 return NULL;
3256         }
3257
3258         fa = builtin_newarray_float(len);
3259
3260         return (jfloatArray) NewLocalRef(env, (jobject) fa);
3261 }
3262
3263
3264 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3265 {
3266         java_doublearray *da;
3267
3268         STATS(jniinvokation();)
3269
3270         if (len < 0) {
3271                 *exceptionptr = new_negativearraysizeexception();
3272                 return NULL;
3273         }
3274
3275         da = builtin_newarray_double(len);
3276
3277         return (jdoubleArray) NewLocalRef(env, (jobject) da);
3278 }
3279
3280
3281 /* Get<PrimitiveType>ArrayElements *********************************************
3282
3283    A family of functions that returns the body of the primitive array.
3284
3285 *******************************************************************************/
3286
3287 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3288                                                                   jboolean *isCopy)
3289 {
3290         STATS(jniinvokation();)
3291
3292     if (isCopy)
3293                 *isCopy = JNI_FALSE;
3294
3295     return array->data;
3296 }
3297
3298
3299 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3300 {
3301         STATS(jniinvokation();)
3302
3303     if (isCopy)
3304                 *isCopy = JNI_FALSE;
3305
3306     return array->data;
3307 }
3308
3309
3310 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3311 {
3312         STATS(jniinvokation();)
3313
3314     if (isCopy)
3315                 *isCopy = JNI_FALSE;
3316
3317     return array->data;
3318 }
3319
3320
3321 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3322 {
3323         STATS(jniinvokation();)
3324
3325     if (isCopy)
3326                 *isCopy = JNI_FALSE;
3327
3328     return array->data;
3329 }
3330
3331
3332 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3333 {
3334         STATS(jniinvokation();)
3335
3336     if (isCopy)
3337                 *isCopy = JNI_FALSE;
3338
3339     return array->data;
3340 }
3341
3342
3343 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3344 {
3345         STATS(jniinvokation();)
3346
3347     if (isCopy)
3348                 *isCopy = JNI_FALSE;
3349
3350     return array->data;
3351 }
3352
3353
3354 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3355 {
3356         STATS(jniinvokation();)
3357
3358     if (isCopy)
3359                 *isCopy = JNI_FALSE;
3360
3361     return array->data;
3362 }
3363
3364
3365 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3366                                                                 jboolean *isCopy)
3367 {
3368         STATS(jniinvokation();)
3369
3370     if (isCopy)
3371                 *isCopy = JNI_FALSE;
3372
3373     return array->data;
3374 }
3375
3376
3377 /* Release<PrimitiveType>ArrayElements *****************************************
3378
3379    A family of functions that informs the VM that the native code no
3380    longer needs access to elems. The elems argument is a pointer
3381    derived from array using the corresponding
3382    Get<PrimitiveType>ArrayElements() function. If necessary, this
3383    function copies back all changes made to elems to the original
3384    array.
3385
3386 *******************************************************************************/
3387
3388 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3389                                                                  jboolean *elems, jint mode)
3390 {
3391         STATS(jniinvokation();)
3392
3393         if (elems != array->data) {
3394                 switch (mode) {
3395                 case JNI_COMMIT:
3396                         MCOPY(array->data, elems, jboolean, array->header.size);
3397                         break;
3398                 case 0:
3399                         MCOPY(array->data, elems, jboolean, array->header.size);
3400                         /* XXX TWISTI how should it be freed? */
3401                         break;
3402                 case JNI_ABORT:
3403                         /* XXX TWISTI how should it be freed? */
3404                         break;
3405                 }
3406         }
3407 }
3408
3409
3410 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3411                                                           jint mode)
3412 {
3413         STATS(jniinvokation();)
3414
3415         if (elems != array->data) {
3416                 switch (mode) {
3417                 case JNI_COMMIT:
3418                         MCOPY(array->data, elems, jboolean, array->header.size);
3419                         break;
3420                 case 0:
3421                         MCOPY(array->data, elems, jboolean, array->header.size);
3422                         /* XXX TWISTI how should it be freed? */
3423                         break;
3424                 case JNI_ABORT:
3425                         /* XXX TWISTI how should it be freed? */
3426                         break;
3427                 }
3428         }
3429 }
3430
3431
3432 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3433                                                           jint mode)
3434 {
3435         STATS(jniinvokation();)
3436
3437         if (elems != array->data) {
3438                 switch (mode) {
3439                 case JNI_COMMIT:
3440                         MCOPY(array->data, elems, jboolean, array->header.size);
3441                         break;
3442                 case 0:
3443                         MCOPY(array->data, elems, jboolean, array->header.size);
3444                         /* XXX TWISTI how should it be freed? */
3445                         break;
3446                 case JNI_ABORT:
3447                         /* XXX TWISTI how should it be freed? */
3448                         break;
3449                 }
3450         }
3451 }
3452
3453
3454 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3455                                                            jint mode)
3456 {
3457         STATS(jniinvokation();)
3458
3459         if (elems != array->data) {
3460                 switch (mode) {
3461                 case JNI_COMMIT:
3462                         MCOPY(array->data, elems, jboolean, array->header.size);
3463                         break;
3464                 case 0:
3465                         MCOPY(array->data, elems, jboolean, array->header.size);
3466                         /* XXX TWISTI how should it be freed? */
3467                         break;
3468                 case JNI_ABORT:
3469                         /* XXX TWISTI how should it be freed? */
3470                         break;
3471                 }
3472         }
3473 }
3474
3475
3476 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3477                                                          jint mode)
3478 {
3479         STATS(jniinvokation();)
3480
3481         if (elems != array->data) {
3482                 switch (mode) {
3483                 case JNI_COMMIT:
3484                         MCOPY(array->data, elems, jboolean, array->header.size);
3485                         break;
3486                 case 0:
3487                         MCOPY(array->data, elems, jboolean, array->header.size);
3488                         /* XXX TWISTI how should it be freed? */
3489                         break;
3490                 case JNI_ABORT:
3491                         /* XXX TWISTI how should it be freed? */
3492                         break;
3493                 }
3494         }
3495 }
3496
3497
3498 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3499                                                           jint mode)
3500 {
3501         STATS(jniinvokation();)
3502
3503         if (elems != array->data) {
3504                 switch (mode) {
3505                 case JNI_COMMIT:
3506                         MCOPY(array->data, elems, jboolean, array->header.size);
3507                         break;
3508                 case 0:
3509                         MCOPY(array->data, elems, jboolean, array->header.size);
3510                         /* XXX TWISTI how should it be freed? */
3511                         break;
3512                 case JNI_ABORT:
3513                         /* XXX TWISTI how should it be freed? */
3514                         break;
3515                 }
3516         }
3517 }
3518
3519
3520 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3521                                                            jint mode)
3522 {
3523         STATS(jniinvokation();)
3524
3525         if (elems != array->data) {
3526                 switch (mode) {
3527                 case JNI_COMMIT:
3528                         MCOPY(array->data, elems, jboolean, array->header.size);
3529                         break;
3530                 case 0:
3531                         MCOPY(array->data, elems, jboolean, array->header.size);
3532                         /* XXX TWISTI how should it be freed? */
3533                         break;
3534                 case JNI_ABORT:
3535                         /* XXX TWISTI how should it be freed? */
3536                         break;
3537                 }
3538         }
3539 }
3540
3541
3542 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3543                                                                 jdouble *elems, jint mode)
3544 {
3545         STATS(jniinvokation();)
3546
3547         if (elems != array->data) {
3548                 switch (mode) {
3549                 case JNI_COMMIT:
3550                         MCOPY(array->data, elems, jboolean, array->header.size);
3551                         break;
3552                 case 0:
3553                         MCOPY(array->data, elems, jboolean, array->header.size);
3554                         /* XXX TWISTI how should it be freed? */
3555                         break;
3556                 case JNI_ABORT:
3557                         /* XXX TWISTI how should it be freed? */
3558                         break;
3559                 }
3560         }
3561 }
3562
3563
3564 /*  Get<PrimitiveType>ArrayRegion **********************************************
3565
3566         A family of functions that copies a region of a primitive array
3567         into a buffer.
3568
3569 *******************************************************************************/
3570
3571 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3572                                                    jsize len, jboolean *buf)
3573 {
3574         STATS(jniinvokation();)
3575
3576     if (start < 0 || len < 0 || start + len > array->header.size)
3577                 *exceptionptr =
3578                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3579
3580     else
3581                 MCOPY(buf, &array->data[start], jboolean, len);
3582 }
3583
3584
3585 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3586                                                 jbyte *buf)
3587 {
3588         STATS(jniinvokation();)
3589
3590     if (start < 0 || len < 0 || start + len > array->header.size) 
3591                 *exceptionptr =
3592                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3593
3594     else
3595                 MCOPY(buf, &array->data[start], jbyte, len);
3596 }
3597
3598
3599 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3600                                                 jchar *buf)
3601 {
3602         STATS(jniinvokation();)
3603
3604     if (start < 0 || len < 0 || start + len > array->header.size)
3605                 *exceptionptr =
3606                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3607
3608     else
3609                 MCOPY(buf, &array->data[start], jchar, len);
3610 }
3611
3612
3613 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3614                                                  jsize len, jshort *buf)
3615 {
3616         STATS(jniinvokation();)
3617
3618     if (start < 0 || len < 0 || start + len > array->header.size)
3619                 *exceptionptr =
3620                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3621
3622     else        
3623                 MCOPY(buf, &array->data[start], jshort, len);
3624 }
3625
3626
3627 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3628                                            jint *buf)
3629 {
3630         STATS(jniinvokation();)
3631
3632     if (start < 0 || len < 0 || start + len > array->header.size)
3633                 *exceptionptr =
3634                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3635
3636     else
3637                 MCOPY(buf, &array->data[start], jint, len);
3638 }
3639
3640
3641 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3642                                                 jlong *buf)
3643 {
3644         STATS(jniinvokation();)
3645
3646     if (start < 0 || len < 0 || start + len > array->header.size)
3647                 *exceptionptr =
3648                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3649
3650     else
3651                 MCOPY(buf, &array->data[start], jlong, len);
3652 }
3653
3654
3655 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3656                                                  jsize len, jfloat *buf)
3657 {
3658         STATS(jniinvokation();)
3659
3660     if (start < 0 || len < 0 || start + len > array->header.size)
3661                 *exceptionptr =
3662                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3663
3664     else
3665                 MCOPY(buf, &array->data[start], jfloat, len);
3666 }
3667
3668
3669 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3670                                                   jsize len, jdouble *buf)
3671 {
3672         STATS(jniinvokation();)
3673
3674     if (start < 0 || len < 0 || start+len>array->header.size)
3675                 *exceptionptr =
3676                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3677
3678     else
3679                 MCOPY(buf, &array->data[start], jdouble, len);
3680 }
3681
3682
3683 /*  Set<PrimitiveType>ArrayRegion **********************************************
3684
3685         A family of functions that copies back a region of a primitive
3686         array from a buffer.
3687
3688 *******************************************************************************/
3689
3690 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3691                                                    jsize len, jboolean *buf)
3692 {
3693         STATS(jniinvokation();)
3694
3695     if (start < 0 || len < 0 || start + len > array->header.size)
3696                 *exceptionptr =
3697                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3698
3699     else
3700                 MCOPY(&array->data[start], buf, jboolean, len);
3701 }
3702
3703
3704 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3705                                                 jbyte *buf)
3706 {
3707         STATS(jniinvokation();)
3708
3709     if (start < 0 || len < 0 || start + len > array->header.size)
3710                 *exceptionptr =
3711                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3712
3713     else
3714                 MCOPY(&array->data[start], buf, jbyte, len);
3715 }
3716
3717
3718 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3719                                                 jchar *buf)
3720 {
3721         STATS(jniinvokation();)
3722
3723     if (start < 0 || len < 0 || start + len > array->header.size)
3724                 *exceptionptr =
3725                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3726
3727     else
3728                 MCOPY(&array->data[start], buf, jchar, len);
3729
3730 }
3731
3732
3733 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3734                                                  jsize len, jshort *buf)
3735 {
3736         STATS(jniinvokation();)
3737
3738     if (start < 0 || len < 0 || start + len > array->header.size)
3739                 *exceptionptr =
3740                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3741
3742     else
3743                 MCOPY(&array->data[start], buf, jshort, len);
3744 }
3745
3746
3747 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3748                                            jint *buf)
3749 {
3750         STATS(jniinvokation();)
3751
3752     if (start < 0 || len < 0 || start + len > array->header.size)
3753                 *exceptionptr =
3754                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3755
3756     else
3757                 MCOPY(&array->data[start], buf, jint, len);
3758
3759 }
3760
3761
3762 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3763                                                 jlong *buf)
3764 {
3765         STATS(jniinvokation();)
3766
3767     if (start < 0 || len < 0 || start + len > array->header.size)
3768                 *exceptionptr =
3769                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3770
3771     else
3772                 MCOPY(&array->data[start], buf, jlong, len);
3773
3774 }
3775
3776
3777 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3778                                                  jsize len, jfloat *buf)
3779 {
3780         STATS(jniinvokation();)
3781
3782     if (start < 0 || len < 0 || start + len > array->header.size)
3783                 *exceptionptr =
3784                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3785
3786     else
3787                 MCOPY(&array->data[start], buf, jfloat, len);
3788
3789 }
3790
3791
3792 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3793                                                   jsize len, jdouble *buf)
3794 {
3795         STATS(jniinvokation();)
3796
3797     if (start < 0 || len < 0 || start + len > array->header.size)
3798                 *exceptionptr =
3799                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3800
3801     else
3802                 MCOPY(&array->data[start], buf, jdouble, len);
3803 }
3804
3805
3806 /* Registering Native Methods *************************************************/
3807
3808 /* RegisterNatives *************************************************************
3809
3810    Registers native methods with the class specified by the clazz
3811    argument. The methods parameter specifies an array of
3812    JNINativeMethod structures that contain the names, signatures, and
3813    function pointers of the native methods. The nMethods parameter
3814    specifies the number of native methods in the array.
3815
3816 *******************************************************************************/
3817
3818 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3819                                          jint nMethods)
3820 {
3821         STATS(jniinvokation();)
3822
3823     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3824
3825     return 0;
3826 }
3827
3828
3829 /* UnregisterNatives ***********************************************************
3830
3831    Unregisters native methods of a class. The class goes back to the
3832    state before it was linked or registered with its native method
3833    functions.
3834
3835    This function should not be used in normal native code. Instead, it
3836    provides special programs a way to reload and relink native
3837    libraries.
3838
3839 *******************************************************************************/
3840
3841 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3842 {
3843         STATS(jniinvokation();)
3844
3845         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3846
3847     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3848
3849     return 0;
3850 }
3851
3852
3853 /* Monitor Operations *********************************************************/
3854
3855 /* MonitorEnter ****************************************************************
3856
3857    Enters the monitor associated with the underlying Java object
3858    referred to by obj.
3859
3860 *******************************************************************************/
3861
3862 jint MonitorEnter(JNIEnv *env, jobject obj)
3863 {
3864         STATS(jniinvokation();)
3865
3866         if (!obj) {
3867                 *exceptionptr = new_nullpointerexception();
3868                 return JNI_ERR;
3869         }
3870
3871 #if defined(USE_THREADS)
3872         builtin_monitorenter(obj);
3873 #endif
3874
3875         return JNI_OK;
3876 }
3877
3878
3879 /* MonitorExit *****************************************************************
3880
3881    The current thread must be the owner of the monitor associated with
3882    the underlying Java object referred to by obj. The thread
3883    decrements the counter indicating the number of times it has
3884    entered this monitor. If the value of the counter becomes zero, the
3885    current thread releases the monitor.
3886
3887 *******************************************************************************/
3888
3889 jint MonitorExit(JNIEnv *env, jobject obj)
3890 {
3891         STATS(jniinvokation();)
3892         if (!obj) {
3893                 *exceptionptr = new_nullpointerexception();
3894                 return JNI_ERR;
3895         }
3896
3897 #if defined(USE_THREADS)
3898         builtin_monitorexit(obj);
3899 #endif
3900
3901         return JNI_OK;
3902 }
3903
3904
3905 /* JavaVM Interface ***********************************************************/
3906
3907 /* GetJavaVM *******************************************************************
3908
3909    Returns the Java VM interface (used in the Invocation API)
3910    associated with the current thread. The result is placed at the
3911    location pointed to by the second argument, vm.
3912
3913 *******************************************************************************/
3914
3915 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3916 {
3917         STATS(jniinvokation();)
3918     *vm = &ptr_jvm;
3919
3920         return 0;
3921 }
3922
3923
3924 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3925 {
3926         STATS(jniinvokation();)
3927         log_text("JNI-Call: GetStringRegion");
3928 }
3929
3930
3931 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3932 {
3933         STATS(jniinvokation();)
3934         log_text("JNI-Call: GetStringUTFRegion");
3935 }
3936
3937
3938 /* GetPrimitiveArrayCritical ***************************************************
3939
3940    Obtain a direct pointer to array elements.
3941
3942 *******************************************************************************/
3943
3944 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3945 {
3946         /* do the same as Kaffe does */
3947
3948         return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3949 }
3950
3951
3952 /* ReleasePrimitiveArrayCritical ***********************************************
3953
3954    No specific documentation.
3955
3956 *******************************************************************************/
3957
3958 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3959                                                                    jint mode)
3960 {
3961         STATS(jniinvokation();)
3962
3963         /* do the same as Kaffe does */
3964
3965         ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
3966 }
3967
3968
3969 /* GetStringCritical ***********************************************************
3970
3971    The semantics of these two functions are similar to the existing
3972    Get/ReleaseStringChars functions.
3973
3974 *******************************************************************************/
3975
3976 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3977 {
3978         STATS(jniinvokation();)
3979
3980         return GetStringChars(env, string, isCopy);
3981 }
3982
3983
3984 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3985 {
3986         STATS(jniinvokation();)
3987
3988         ReleaseStringChars(env, string, cstring);
3989 }
3990
3991
3992 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3993 {
3994         STATS(jniinvokation();)
3995         log_text("JNI-Call: NewWeakGlobalRef");
3996
3997         return obj;
3998 }
3999
4000
4001 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
4002 {
4003         STATS(jniinvokation();)
4004         log_text("JNI-Call: DeleteWeakGlobalRef");
4005
4006         /* empty */
4007 }
4008
4009
4010 /* NewGlobalRef ****************************************************************
4011
4012    Creates a new global reference to the object referred to by the obj
4013    argument.
4014
4015 *******************************************************************************/
4016     
4017 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4018 {
4019         java_lang_Integer *refcount;
4020         java_objectheader *newval;
4021
4022         STATS(jniinvokation();)
4023
4024 #if defined(USE_THREADS)
4025         builtin_monitorenter(*global_ref_table);
4026 #endif
4027         
4028         refcount = (java_lang_Integer *)
4029                 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4030
4031         if (refcount == NULL) {
4032                 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4033
4034                 if (newval == NULL) {
4035 #if defined(USE_THREADS)
4036                         builtin_monitorexit(*global_ref_table);
4037 #endif
4038                         return NULL;
4039                 }
4040
4041                 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4042
4043         } else {
4044                 /* we can access the object itself, as we are in a
4045            synchronized section */
4046
4047                 refcount->value++;
4048         }
4049
4050 #if defined(USE_THREADS)
4051         builtin_monitorexit(*global_ref_table);
4052 #endif
4053
4054         return lobj;
4055 }
4056
4057
4058 /* DeleteGlobalRef *************************************************************
4059
4060    Deletes the global reference pointed to by globalRef.
4061
4062 *******************************************************************************/
4063
4064 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4065 {
4066         java_lang_Integer *refcount;
4067         s4                 val;
4068
4069         STATS(jniinvokation();)
4070
4071 #if defined(USE_THREADS)
4072         builtin_monitorenter(*global_ref_table);
4073 #endif
4074
4075         refcount = (java_lang_Integer *)
4076                 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4077
4078         if (refcount == NULL) {
4079                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4080                 return;
4081         }
4082
4083         /* we can access the object itself, as we are in a synchronized
4084            section */
4085
4086         val = refcount->value - 1;
4087
4088         if (val == 0) {
4089                 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4090                                                          NULL);
4091
4092         } else {
4093                 /* we do not create a new object, but set the new value into
4094            the old one */
4095
4096                 refcount->value = val;
4097         }
4098
4099 #if defined(USE_THREADS)
4100         builtin_monitorexit(*global_ref_table);
4101 #endif
4102 }
4103
4104
4105 /* ExceptionCheck **************************************************************
4106
4107    Returns JNI_TRUE when there is a pending exception; otherwise,
4108    returns JNI_FALSE.
4109
4110 *******************************************************************************/
4111
4112 jboolean ExceptionCheck(JNIEnv *env)
4113 {
4114         STATS(jniinvokation();)
4115         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4116 }
4117
4118
4119 /* New JNI 1.4 functions ******************************************************/
4120
4121 /* NewDirectByteBuffer *********************************************************
4122
4123    Allocates and returns a direct java.nio.ByteBuffer referring to the
4124    block of memory starting at the memory address address and
4125    extending capacity bytes.
4126
4127 *******************************************************************************/
4128
4129 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4130 {
4131         java_nio_DirectByteBufferImpl *nbuf;
4132 #if SIZEOF_VOID_P == 8
4133         gnu_classpath_Pointer64 *paddress;
4134 #else
4135         gnu_classpath_Pointer32 *paddress;
4136 #endif
4137
4138         STATS(jniinvokation();)
4139
4140         log_text("JNI-NewDirectByteBuffer: called");
4141
4142         /* allocate a java.nio.DirectByteBufferImpl object */
4143
4144         if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4145                 return NULL;
4146
4147         /* alocate a gnu.classpath.Pointer{32,64} object */
4148
4149 #if SIZEOF_VOID_P == 8
4150         if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4151 #else
4152         if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4153 #endif
4154                 return NULL;
4155
4156         /* fill gnu.classpath.Pointer{32,64} with address */
4157
4158         paddress->data = (ptrint) address;
4159
4160         /* fill java.nio.Buffer object */
4161
4162         nbuf->cap     = (s4) capacity;
4163         nbuf->limit   = (s4) capacity;
4164         nbuf->pos     = 0;
4165         nbuf->address = (gnu_classpath_Pointer *) paddress;
4166
4167         /* add local reference and return the value */
4168
4169         return NewLocalRef(env, (jobject) nbuf);
4170 }
4171
4172
4173 /* GetDirectBufferAddress ******************************************************
4174
4175    Fetches and returns the starting address of the memory region
4176    referenced by the given direct java.nio.Buffer.
4177
4178 *******************************************************************************/
4179
4180 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4181 {
4182         java_nio_DirectByteBufferImpl *nbuf;
4183 #if SIZEOF_VOID_P == 8
4184         gnu_classpath_Pointer64       *address;
4185 #else
4186         gnu_classpath_Pointer32       *address;
4187 #endif
4188
4189         STATS(jniinvokation();)
4190
4191 #if 0
4192         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4193                 return NULL;
4194 #endif
4195
4196         nbuf = (java_nio_DirectByteBufferImpl *) buf;
4197
4198 #if SIZEOF_VOID_P == 8
4199         address = (gnu_classpath_Pointer64 *) nbuf->address;
4200 #else
4201         address = (gnu_classpath_Pointer32 *) nbuf->address;
4202 #endif
4203
4204         return (void *) address->data;
4205 }
4206
4207
4208 /* GetDirectBufferCapacity *****************************************************
4209
4210    Fetches and returns the capacity in bytes of the memory region
4211    referenced by the given direct java.nio.Buffer.
4212
4213 *******************************************************************************/
4214
4215 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4216 {
4217         java_nio_Buffer *nbuf;
4218
4219         STATS(jniinvokation();)
4220
4221         if (buf == NULL)
4222                 return -1;
4223
4224         nbuf = (java_nio_Buffer *) buf;
4225
4226         return (jlong) nbuf->cap;
4227 }
4228
4229
4230 jint DestroyJavaVM(JavaVM *vm)
4231 {
4232         STATS(jniinvokation();)
4233         log_text("DestroyJavaVM called");
4234
4235         return 0;
4236 }
4237
4238
4239 /* AttachCurrentThread *********************************************************
4240
4241    Attaches the current thread to a Java VM. Returns a JNI interface
4242    pointer in the JNIEnv argument.
4243
4244    Trying to attach a thread that is already attached is a no-op.
4245
4246    A native thread cannot be attached simultaneously to two Java VMs.
4247
4248    When a thread is attached to the VM, the context class loader is
4249    the bootstrap loader.
4250
4251 *******************************************************************************/
4252
4253 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4254 {
4255         STATS(jniinvokation();)
4256
4257         log_text("AttachCurrentThread called");
4258
4259 #if !defined(HAVE___THREAD)
4260 /*      cacao_thread_attach();*/
4261 #else
4262         #error "No idea how to implement that. Perhaps Stefan knows"
4263 #endif
4264
4265         *env = &ptr_env;
4266
4267         return 0;
4268 }
4269
4270
4271 jint DetachCurrentThread(JavaVM *vm)
4272 {
4273         STATS(jniinvokation();)
4274         log_text("DetachCurrentThread called");
4275
4276         return 0;
4277 }
4278
4279
4280 /* GetEnv **********************************************************************
4281
4282    If the current thread is not attached to the VM, sets *env to NULL,
4283    and returns JNI_EDETACHED. If the specified version is not
4284    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4285    sets *env to the appropriate interface, and returns JNI_OK.
4286
4287 *******************************************************************************/
4288
4289 jint GetEnv(JavaVM *vm, void **env, jint version)
4290 {
4291         STATS(jniinvokation();)
4292
4293 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4294         if (thread_getself() == NULL) {
4295                 *env = NULL;
4296
4297                 return JNI_EDETACHED;
4298         }
4299 #endif
4300
4301         if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4302                 (version == JNI_VERSION_1_4)) {
4303                 *env = &ptr_env;
4304
4305                 return JNI_OK;
4306         }
4307
4308 #if defined(ENABLE_JVMTI)
4309         if (version == JVMTI_VERSION_1_0) {
4310                 *env = (void *) new_jvmtienv();
4311
4312                 if (env != NULL)
4313                         return JNI_OK;
4314         }
4315 #endif
4316         
4317         *env = NULL;
4318
4319         return JNI_EVERSION;
4320 }
4321
4322
4323
4324 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4325 {
4326         STATS(jniinvokation();)
4327         log_text("AttachCurrentThreadAsDaemon called");
4328
4329         return 0;
4330 }
4331
4332
4333 /* JNI invocation table *******************************************************/
4334
4335 const struct JNIInvokeInterface JNI_JavaVMTable = {
4336         NULL,
4337         NULL,
4338         NULL,
4339
4340         DestroyJavaVM,
4341         AttachCurrentThread,
4342         DetachCurrentThread,
4343         GetEnv,
4344         AttachCurrentThreadAsDaemon
4345 };
4346
4347
4348 /* JNI function table *********************************************************/
4349
4350 struct JNINativeInterface JNI_JNIEnvTable = {
4351         NULL,
4352         NULL,
4353         NULL,
4354         NULL,    
4355         &GetVersion,
4356
4357         &DefineClass,
4358         &FindClass,
4359         &FromReflectedMethod,
4360         &FromReflectedField,
4361         &ToReflectedMethod,
4362         &GetSuperclass,
4363         &IsAssignableFrom,
4364         &ToReflectedField,
4365
4366         &Throw,
4367         &ThrowNew,
4368         &ExceptionOccurred,
4369         &ExceptionDescribe,
4370         &ExceptionClear,
4371         &FatalError,
4372         &PushLocalFrame,
4373         &PopLocalFrame,
4374
4375         &NewGlobalRef,
4376         &DeleteGlobalRef,
4377         &DeleteLocalRef,
4378         &IsSameObject,
4379         &NewLocalRef,
4380         &EnsureLocalCapacity,
4381
4382         &AllocObject,
4383         &NewObject,
4384         &NewObjectV,
4385         &NewObjectA,
4386
4387         &GetObjectClass,
4388         &IsInstanceOf,
4389
4390         &GetMethodID,
4391
4392         &CallObjectMethod,
4393         &CallObjectMethodV,
4394         &CallObjectMethodA,
4395         &CallBooleanMethod,
4396         &CallBooleanMethodV,
4397         &CallBooleanMethodA,
4398         &CallByteMethod,
4399         &CallByteMethodV,
4400         &CallByteMethodA,
4401         &CallCharMethod,
4402         &CallCharMethodV,
4403         &CallCharMethodA,
4404         &CallShortMethod,
4405         &CallShortMethodV,
4406         &CallShortMethodA,
4407         &CallIntMethod,
4408         &CallIntMethodV,
4409         &CallIntMethodA,
4410         &CallLongMethod,
4411         &CallLongMethodV,
4412         &CallLongMethodA,
4413         &CallFloatMethod,
4414         &CallFloatMethodV,
4415         &CallFloatMethodA,
4416         &CallDoubleMethod,
4417         &CallDoubleMethodV,
4418         &CallDoubleMethodA,
4419         &CallVoidMethod,
4420         &CallVoidMethodV,
4421         &CallVoidMethodA,
4422
4423         &CallNonvirtualObjectMethod,
4424         &CallNonvirtualObjectMethodV,
4425         &CallNonvirtualObjectMethodA,
4426         &CallNonvirtualBooleanMethod,
4427         &CallNonvirtualBooleanMethodV,
4428         &CallNonvirtualBooleanMethodA,
4429         &CallNonvirtualByteMethod,
4430         &CallNonvirtualByteMethodV,
4431         &CallNonvirtualByteMethodA,
4432         &CallNonvirtualCharMethod,
4433         &CallNonvirtualCharMethodV,
4434         &CallNonvirtualCharMethodA,
4435         &CallNonvirtualShortMethod,
4436         &CallNonvirtualShortMethodV,
4437         &CallNonvirtualShortMethodA,
4438         &CallNonvirtualIntMethod,
4439         &CallNonvirtualIntMethodV,
4440         &CallNonvirtualIntMethodA,
4441         &CallNonvirtualLongMethod,
4442         &CallNonvirtualLongMethodV,
4443         &CallNonvirtualLongMethodA,
4444         &CallNonvirtualFloatMethod,
4445         &CallNonvirtualFloatMethodV,
4446         &CallNonvirtualFloatMethodA,
4447         &CallNonvirtualDoubleMethod,
4448         &CallNonvirtualDoubleMethodV,
4449         &CallNonvirtualDoubleMethodA,
4450         &CallNonvirtualVoidMethod,
4451         &CallNonvirtualVoidMethodV,
4452         &CallNonvirtualVoidMethodA,
4453
4454         &GetFieldID,
4455
4456         &GetObjectField,
4457         &GetBooleanField,
4458         &GetByteField,
4459         &GetCharField,
4460         &GetShortField,
4461         &GetIntField,
4462         &GetLongField,
4463         &GetFloatField,
4464         &GetDoubleField,
4465         &SetObjectField,
4466         &SetBooleanField,
4467         &SetByteField,
4468         &SetCharField,
4469         &SetShortField,
4470         &SetIntField,
4471         &SetLongField,
4472         &SetFloatField,
4473         &SetDoubleField,
4474
4475         &GetStaticMethodID,
4476
4477         &CallStaticObjectMethod,
4478         &CallStaticObjectMethodV,
4479         &CallStaticObjectMethodA,
4480         &CallStaticBooleanMethod,
4481         &CallStaticBooleanMethodV,
4482         &CallStaticBooleanMethodA,
4483         &CallStaticByteMethod,
4484         &CallStaticByteMethodV,
4485         &CallStaticByteMethodA,
4486         &CallStaticCharMethod,
4487         &CallStaticCharMethodV,
4488         &CallStaticCharMethodA,
4489         &CallStaticShortMethod,
4490         &CallStaticShortMethodV,
4491         &CallStaticShortMethodA,
4492         &CallStaticIntMethod,
4493         &CallStaticIntMethodV,
4494         &CallStaticIntMethodA,
4495         &CallStaticLongMethod,
4496         &CallStaticLongMethodV,
4497         &CallStaticLongMethodA,
4498         &CallStaticFloatMethod,
4499         &CallStaticFloatMethodV,
4500         &CallStaticFloatMethodA,
4501         &CallStaticDoubleMethod,
4502         &CallStaticDoubleMethodV,
4503         &CallStaticDoubleMethodA,
4504         &CallStaticVoidMethod,
4505         &CallStaticVoidMethodV,
4506         &CallStaticVoidMethodA,
4507
4508         &GetStaticFieldID,
4509
4510         &GetStaticObjectField,
4511         &GetStaticBooleanField,
4512         &GetStaticByteField,
4513         &GetStaticCharField,
4514         &GetStaticShortField,
4515         &GetStaticIntField,
4516         &GetStaticLongField,
4517         &GetStaticFloatField,
4518         &GetStaticDoubleField,
4519         &SetStaticObjectField,
4520         &SetStaticBooleanField,
4521         &SetStaticByteField,
4522         &SetStaticCharField,
4523         &SetStaticShortField,
4524         &SetStaticIntField,
4525         &SetStaticLongField,
4526         &SetStaticFloatField,
4527         &SetStaticDoubleField,
4528
4529         &NewString,
4530         &GetStringLength,
4531         &GetStringChars,
4532         &ReleaseStringChars,
4533
4534         &NewStringUTF,
4535         &GetStringUTFLength,
4536         &GetStringUTFChars,
4537         &ReleaseStringUTFChars,
4538
4539         &GetArrayLength,
4540
4541         &NewObjectArray,
4542         &GetObjectArrayElement,
4543         &SetObjectArrayElement,
4544
4545         &NewBooleanArray,
4546         &NewByteArray,
4547         &NewCharArray,
4548         &NewShortArray,
4549         &NewIntArray,
4550         &NewLongArray,
4551         &NewFloatArray,
4552         &NewDoubleArray,
4553
4554         &GetBooleanArrayElements,
4555         &GetByteArrayElements,
4556         &GetCharArrayElements,
4557         &GetShortArrayElements,
4558         &GetIntArrayElements,
4559         &GetLongArrayElements,
4560         &GetFloatArrayElements,
4561         &GetDoubleArrayElements,
4562
4563         &ReleaseBooleanArrayElements,
4564         &ReleaseByteArrayElements,
4565         &ReleaseCharArrayElements,
4566         &ReleaseShortArrayElements,
4567         &ReleaseIntArrayElements,
4568         &ReleaseLongArrayElements,
4569         &ReleaseFloatArrayElements,
4570         &ReleaseDoubleArrayElements,
4571
4572         &GetBooleanArrayRegion,
4573         &GetByteArrayRegion,
4574         &GetCharArrayRegion,
4575         &GetShortArrayRegion,
4576         &GetIntArrayRegion,
4577         &GetLongArrayRegion,
4578         &GetFloatArrayRegion,
4579         &GetDoubleArrayRegion,
4580         &SetBooleanArrayRegion,
4581         &SetByteArrayRegion,
4582         &SetCharArrayRegion,
4583         &SetShortArrayRegion,
4584         &SetIntArrayRegion,
4585         &SetLongArrayRegion,
4586         &SetFloatArrayRegion,
4587         &SetDoubleArrayRegion,
4588
4589         &RegisterNatives,
4590         &UnregisterNatives,
4591
4592         &MonitorEnter,
4593         &MonitorExit,
4594
4595         &GetJavaVM,
4596
4597         /* new JNI 1.2 functions */
4598
4599         &GetStringRegion,
4600         &GetStringUTFRegion,
4601
4602         &GetPrimitiveArrayCritical,
4603         &ReleasePrimitiveArrayCritical,
4604
4605         &GetStringCritical,
4606         &ReleaseStringCritical,
4607
4608         &NewWeakGlobalRef,
4609         &DeleteWeakGlobalRef,
4610
4611         &ExceptionCheck,
4612
4613         /* new JNI 1.4 functions */
4614
4615         &NewDirectByteBuffer,
4616         &GetDirectBufferAddress,
4617         &GetDirectBufferCapacity
4618 };
4619
4620
4621 /* Invocation API Functions ***************************************************/
4622
4623 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4624
4625    Returns a default configuration for the Java VM.
4626
4627 *******************************************************************************/
4628
4629 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4630 {
4631         JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4632
4633         /* GNU classpath currently supports JNI 1.2 */
4634
4635         _vm_args->version = JNI_VERSION_1_2;
4636
4637         return 0;
4638 }
4639
4640
4641 /* JNI_GetCreatedJavaVMs *******************************************************
4642
4643    Returns all Java VMs that have been created. Pointers to VMs are written in
4644    the buffer vmBuf in the order they are created. At most bufLen number of
4645    entries will be written. The total number of created VMs is returned in
4646    *nVMs.
4647
4648 *******************************************************************************/
4649
4650 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4651 {
4652         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4653
4654         return 0;
4655 }
4656
4657
4658 /* JNI_CreateJavaVM ************************************************************
4659
4660    Loads and initializes a Java VM. The current thread becomes the main thread.
4661    Sets the env argument to the JNI interface pointer of the main thread.
4662
4663 *******************************************************************************/
4664
4665 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4666 {
4667         const struct JNIInvokeInterface *vm;
4668         struct JNINativeInterface *env;
4669
4670         vm = &JNI_JavaVMTable;
4671         env = &JNI_JNIEnvTable;
4672
4673         *p_vm = (JavaVM *) vm;
4674         *p_env = (JNIEnv *) env;
4675
4676         return 0;
4677 }
4678
4679
4680 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4681                                                                            jobject obj, java_objectarray *params)
4682 {
4683         jni_callblock *blk;
4684         jobject        o;
4685         s4             argcount;
4686         s4             paramcount;
4687
4688         if (methodID == 0) {
4689                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
4690                 return NULL;
4691         }
4692
4693         argcount = methodID->parseddesc->paramcount;
4694         paramcount = argcount;
4695
4696         /* if method is non-static, remove the `this' pointer */
4697
4698         if (!(methodID->flags & ACC_STATIC))
4699                 paramcount--;
4700
4701         /* the method is an instance method the obj has to be an instance of the 
4702            class the method belongs to. For static methods the obj parameter
4703            is ignored. */
4704
4705         if (!(methodID->flags & ACC_STATIC) && obj &&
4706                 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4707                 *exceptionptr =
4708                         new_exception_message(string_java_lang_IllegalArgumentException,
4709                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4710                 return NULL;
4711         }
4712
4713         if (((params == NULL) && (paramcount != 0)) ||
4714                 (params && (params->header.size != paramcount))) {
4715                 *exceptionptr =
4716                         new_exception(string_java_lang_IllegalArgumentException);
4717                 return NULL;
4718         }
4719
4720
4721         if (!(methodID->flags & ACC_STATIC) && !obj)  {
4722                 *exceptionptr =
4723                         new_exception_message(string_java_lang_NullPointerException,
4724                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4725                 return NULL;
4726         }
4727
4728         if ((methodID->flags & ACC_STATIC) && (obj))
4729                 obj = NULL;
4730
4731         if (obj) {
4732                 if ((methodID->flags & ACC_ABSTRACT) ||
4733                         (methodID->class->flags & ACC_INTERFACE)) {
4734                         methodID = get_virtual(obj, methodID);
4735                 }
4736         }
4737
4738         blk = MNEW(jni_callblock, argcount);
4739
4740         if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4741                                                                                  params))
4742                 return NULL;
4743
4744         switch (methodID->parseddesc->returntype.decltype) {
4745         case TYPE_VOID:
4746                 (void) asm_calljavafunction2(methodID, argcount,
4747                                                                          argcount * sizeof(jni_callblock),
4748                                                                          blk);
4749                 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4750                 break;
4751
4752         case PRIMITIVETYPE_INT: {
4753                 s4 i;
4754                 i = asm_calljavafunction2int(methodID, argcount,
4755                                                                          argcount * sizeof(jni_callblock),
4756                                                                          blk);
4757
4758                 o = native_new_and_init_int(class_java_lang_Integer, i);
4759         }
4760         break;
4761
4762         case PRIMITIVETYPE_BYTE: {
4763                 s4 i;
4764                 i = asm_calljavafunction2int(methodID, argcount,
4765                                                                          argcount * sizeof(jni_callblock),
4766                                                                          blk);
4767
4768 /*              o = native_new_and_init_int(class_java_lang_Byte, i); */
4769                 o = builtin_new(class_java_lang_Byte);
4770                 CallVoidMethod(env,
4771                                            o,
4772                                            class_resolvemethod(o->vftbl->class,
4773                                                                                    utf_init,
4774                                                                                    utf_byte__void),
4775                                            i);
4776         }
4777         break;
4778
4779         case PRIMITIVETYPE_CHAR: {
4780                 s4 intVal;
4781                 intVal = asm_calljavafunction2int(methodID,
4782                                                                                   argcount,
4783                                                                                   argcount * sizeof(jni_callblock),
4784                                                                                   blk);
4785                 o = builtin_new(class_java_lang_Character);
4786                 CallVoidMethod(env,
4787                                            o,
4788                                            class_resolvemethod(o->vftbl->class,
4789                                                                                    utf_init,
4790                                                                                    utf_char__void),
4791                                            intVal);
4792         }
4793         break;
4794
4795         case PRIMITIVETYPE_SHORT: {
4796                 s4 intVal;
4797                 intVal = asm_calljavafunction2int(methodID,
4798                                                                                   argcount,
4799                                                                                   argcount * sizeof(jni_callblock),
4800                                                                                   blk);
4801                 o = builtin_new(class_java_lang_Short);
4802                 CallVoidMethod(env,
4803                                            o,
4804                                            class_resolvemethod(o->vftbl->class,
4805                                                                                    utf_init,
4806                                                                                    utf_short__void),
4807                                            intVal);
4808         }
4809         break;
4810
4811         case PRIMITIVETYPE_BOOLEAN: {
4812                 s4 intVal;
4813                 intVal = asm_calljavafunction2int(methodID,
4814                                                                                   argcount,
4815                                                                                   argcount * sizeof(jni_callblock),
4816                                                                                   blk);
4817                 o = builtin_new(class_java_lang_Boolean);
4818                 CallVoidMethod(env,
4819                                            o,
4820                                            class_resolvemethod(o->vftbl->class,
4821                                                                                    utf_init,
4822                                                                                    utf_boolean__void),
4823                                            intVal);
4824         }
4825         break;
4826
4827         case PRIMITIVETYPE_LONG: {
4828                 jlong longVal;
4829                 longVal = asm_calljavafunction2long(methodID,
4830                                                                                         argcount,
4831                                                                                         argcount * sizeof(jni_callblock),
4832                                                                                         blk);
4833                 o = builtin_new(class_java_lang_Long);
4834                 CallVoidMethod(env,
4835                                            o,
4836                                            class_resolvemethod(o->vftbl->class,
4837                                                                                    utf_init,
4838                                                                                    utf_long__void),
4839                                            longVal);
4840         }
4841         break;
4842
4843         case PRIMITIVETYPE_FLOAT: {
4844                 jdouble floatVal;       
4845                 floatVal = asm_calljavafunction2float(methodID,
4846                                                                                           argcount,
4847                                                                                           argcount * sizeof(jni_callblock),
4848                                                                                           blk);
4849                 o = builtin_new(class_java_lang_Float);
4850                 CallVoidMethod(env,
4851                                            o,
4852                                            class_resolvemethod(o->vftbl->class,
4853                                                                                    utf_init,
4854                                                                                    utf_float__void),
4855                                            floatVal);
4856         }
4857         break;
4858
4859         case PRIMITIVETYPE_DOUBLE: {
4860                 jdouble doubleVal;
4861                 doubleVal = asm_calljavafunction2double(methodID,
4862                                                                                                 argcount,
4863                                                                                                 argcount * sizeof(jni_callblock),
4864                                                                                                 blk);
4865                 o = builtin_new(class_java_lang_Double);
4866                 CallVoidMethod(env,
4867                                            o,
4868                                            class_resolvemethod(o->vftbl->class,
4869                                                                                    utf_init,
4870                                                                                    utf_double__void),
4871                                            doubleVal);
4872         }
4873         break;
4874
4875         case TYPE_ADR:
4876                 o = asm_calljavafunction2(methodID, argcount,
4877                                                                   argcount * sizeof(jni_callblock), blk);
4878                 break;
4879
4880         default:
4881                 /* if this happens the exception has already been set by              */
4882                 /* fill_callblock_from_objectarray                                    */
4883
4884                 MFREE(blk, jni_callblock, argcount);
4885                 return (jobject *) 0;
4886         }
4887
4888         MFREE(blk, jni_callblock, argcount);
4889
4890         if (*exceptionptr) {
4891                 java_objectheader *cause;
4892
4893                 cause = *exceptionptr;
4894
4895                 /* clear exception pointer, we are calling JIT code again */
4896
4897                 *exceptionptr = NULL;
4898
4899                 *exceptionptr =
4900                         new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4901                                                                         (java_lang_Throwable *) cause);
4902         }
4903
4904         return (jobject *) o;
4905 }
4906
4907
4908 /*
4909  * These are local overrides for various environment variables in Emacs.
4910  * Please do not remove this and leave it at the end of the file, where
4911  * Emacs will automagically detect them.
4912  * ---------------------------------------------------------------------
4913  * Local variables:
4914  * mode: c
4915  * indent-tabs-mode: t
4916  * c-basic-offset: 4
4917  * tab-width: 4
4918  * End:
4919  */