fix bug when calling Java method with return type long
[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 3429 2005-10-13 13:48:21Z edwin $
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
1187
1188 /* EnsureLocalCapacity *********************************************************
1189
1190    Ensures that at least a given number of local references can be
1191    created in the current thread
1192
1193 *******************************************************************************/
1194
1195 jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
1196 {
1197         localref_table *lrt;
1198
1199         STATS(jniinvokation();)
1200
1201         /* get local reference table (thread specific) */
1202
1203         lrt = LOCALREFTABLE;
1204
1205         /* check if capacity elements are available in the local references table */
1206
1207         if ((lrt->used + capacity) > lrt->capacity) {
1208                 *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
1209                 return -1;
1210         }
1211
1212         return 0;
1213 }
1214
1215
1216 /* AllocObject *****************************************************************
1217
1218    Allocates a new Java object without invoking any of the
1219    constructors for the object. Returns a reference to the object.
1220
1221 *******************************************************************************/
1222
1223 jobject AllocObject(JNIEnv *env, jclass clazz)
1224 {
1225         java_objectheader *o;
1226
1227         STATS(jniinvokation();)
1228
1229         if ((clazz->flags & ACC_INTERFACE) || (clazz->flags & ACC_ABSTRACT)) {
1230                 *exceptionptr =
1231                         new_exception_utfmessage(string_java_lang_InstantiationException,
1232                                                                          clazz->name);
1233                 return NULL;
1234         }
1235                 
1236         o = builtin_new(clazz);
1237
1238         return NewLocalRef(env, o);
1239 }
1240
1241
1242 /* NewObject *******************************************************************
1243
1244    Programmers place all arguments that are to be passed to the
1245    constructor immediately following the methodID
1246    argument. NewObject() accepts these arguments and passes them to
1247    the Java method that the programmer wishes to invoke.
1248
1249 *******************************************************************************/
1250
1251 jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1252 {
1253         java_objectheader *o;
1254         va_list            ap;
1255
1256         STATS(jniinvokation();)
1257
1258         /* create object */
1259
1260         o = builtin_new(clazz);
1261         
1262         if (!o)
1263                 return NULL;
1264
1265         /* call constructor */
1266
1267         va_start(ap, methodID);
1268         cacao_jni_CallVoidMethod(o, methodID, ap);
1269         va_end(ap);
1270
1271         return NewLocalRef(env, o);
1272 }
1273
1274
1275 /*********************************************************************************** 
1276
1277        Constructs a new Java object
1278        arguments that are to be passed to the constructor are placed in va_list args 
1279
1280 ***********************************************************************************/
1281
1282 jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
1283 {
1284         STATS(jniinvokation();)
1285
1286         log_text("JNI-Call: NewObjectV: IMPLEMENT ME!");
1287
1288         return NewLocalRef(env, NULL);
1289 }
1290
1291
1292 /*********************************************************************************** 
1293
1294         Constructs a new Java object
1295         arguments that are to be passed to the constructor are placed in 
1296         args array of jvalues 
1297
1298 ***********************************************************************************/
1299
1300 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
1301 {
1302         STATS(jniinvokation();)
1303
1304         log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
1305
1306         return NewLocalRef(env, NULL);
1307 }
1308
1309
1310 /* GetObjectClass **************************************************************
1311
1312  Returns the class of an object.
1313
1314 *******************************************************************************/
1315
1316 jclass GetObjectClass(JNIEnv *env, jobject obj)
1317 {
1318         classinfo *c;
1319         STATS(jniinvokation();)
1320         
1321         if (!obj || !obj->vftbl)
1322                 return NULL;
1323
1324         c = obj->vftbl->class;
1325         use_class_as_object(c);
1326         return c;
1327 }
1328
1329
1330 /* IsInstanceOf ****************************************************************
1331
1332    Tests whether an object is an instance of a class.
1333
1334 *******************************************************************************/
1335
1336 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1337 {
1338         STATS(jniinvokation();)
1339
1340         return Java_java_lang_VMClass_isInstance(env,
1341                                                                                          NULL,
1342                                                                                          (java_lang_Class *) clazz,
1343                                                                                          (java_lang_Object *) obj);
1344 }
1345
1346
1347 /***************** converts a java.lang.reflect.Field to a field ID ***************/
1348  
1349 jfieldID FromReflectedField(JNIEnv* env, jobject field)
1350 {
1351         java_lang_reflect_Field *f;
1352         classinfo *c;
1353         jfieldID fid;   /* the JNI-fieldid of the wrapping object */
1354         STATS(jniinvokation();)
1355         /*log_text("JNI-Call: FromReflectedField");*/
1356
1357         f=(java_lang_reflect_Field *)field;
1358         if (f==0) return 0;
1359         c=(classinfo*)(f->declaringClass);
1360         if ( (f->slot<0) || (f->slot>=c->fieldscount)) {
1361                 /*this usually means a severe internal cacao error or somebody
1362                 tempered around with the reflected method*/
1363                 log_text("error illegal slot for field in class(FromReflectedField)");
1364                 assert(0);
1365         }
1366         fid=&(c->fields[f->slot]);
1367         return fid;
1368 }
1369
1370
1371 /**********************************************************************************
1372
1373         converts a method ID to a java.lang.reflect.Method or 
1374         java.lang.reflect.Constructor object
1375
1376 **********************************************************************************/
1377
1378 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1379 {
1380         log_text("JNI-Call: ToReflectedMethod");
1381         STATS(jniinvokation();)
1382
1383         return NULL;
1384 }
1385
1386
1387 /* GetMethodID *****************************************************************
1388
1389    returns the method ID for an instance method
1390
1391 *******************************************************************************/
1392
1393 jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *sig)
1394 {
1395         methodinfo *m;
1396
1397         STATS(jniinvokation();)
1398
1399         m = class_resolvemethod(clazz, 
1400                                                         utf_new_char((char *) name), 
1401                                                         utf_new_char((char *) sig));
1402
1403         if (!m || (m->flags & ACC_STATIC)) {
1404                 *exceptionptr =
1405                         new_exception_message(string_java_lang_NoSuchMethodError, name);
1406
1407                 return NULL;
1408         }
1409
1410         return m;
1411 }
1412
1413
1414 /******************** JNI-functions for calling instance methods ******************/
1415
1416 jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1417 {
1418         java_objectheader* ret;
1419         va_list            vaargs;
1420
1421         STATS(jniinvokation();)
1422
1423         va_start(vaargs, methodID);
1424         ret = callObjectMethod(obj, methodID, vaargs);
1425         va_end(vaargs);
1426
1427         return NewLocalRef(env, ret);
1428 }
1429
1430
1431 jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1432 {
1433         java_objectheader* ret;
1434
1435         STATS(jniinvokation();)
1436
1437         ret = callObjectMethod(obj, methodID, args);
1438
1439         return NewLocalRef(env, ret);
1440 }
1441
1442
1443 jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1444 {
1445         STATS(jniinvokation();)
1446
1447         log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
1448
1449         return NewLocalRef(env, NULL);
1450 }
1451
1452
1453
1454
1455 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1456 {
1457         jboolean ret;
1458         va_list vaargs;
1459         STATS(jniinvokation();)
1460
1461 /*      log_text("JNI-Call: CallBooleanMethod");*/
1462
1463         va_start(vaargs,methodID);
1464         ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1465         va_end(vaargs);
1466         return ret;
1467
1468 }
1469
1470 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1471 {
1472         STATS(jniinvokation();)
1473
1474         return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
1475
1476 }
1477
1478 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1479 {
1480         STATS(jniinvokation();)
1481         log_text("JNI-Call: CallBooleanMethodA");
1482
1483         return 0;
1484 }
1485
1486 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
1487 {
1488         jbyte ret;
1489         va_list vaargs;
1490         STATS(jniinvokation();)
1491
1492 /*      log_text("JNI-Call: CallVyteMethod");*/
1493
1494         va_start(vaargs,methodID);
1495         ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
1496         va_end(vaargs);
1497         return ret;
1498
1499 }
1500
1501 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1502 {
1503 /*      log_text("JNI-Call: CallByteMethodV");*/
1504         STATS(jniinvokation();)
1505
1506         return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
1507 }
1508
1509
1510 jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1511 {
1512         log_text("JNI-Call: CallByteMethodA");
1513         STATS(jniinvokation();)
1514
1515         return 0;
1516 }
1517
1518
1519 jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1520 {
1521         jchar ret;
1522         va_list vaargs;
1523         STATS(jniinvokation();)
1524
1525 /*      log_text("JNI-Call: CallCharMethod");*/
1526
1527         va_start(vaargs,methodID);
1528         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
1529         va_end(vaargs);
1530
1531         return ret;
1532 }
1533
1534
1535 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1536 {
1537         STATS(jniinvokation();)
1538
1539 /*      log_text("JNI-Call: CallCharMethodV");*/
1540         return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
1541 }
1542
1543
1544 jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1545 {
1546         STATS(jniinvokation();)
1547
1548         log_text("JNI-Call: CallCharMethodA");
1549
1550         return 0;
1551 }
1552
1553
1554 jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1555 {
1556         jshort ret;
1557         va_list vaargs;
1558         STATS(jniinvokation();)
1559
1560 /*      log_text("JNI-Call: CallShortMethod");*/
1561
1562         va_start(vaargs, methodID);
1563         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
1564         va_end(vaargs);
1565
1566         return ret;
1567 }
1568
1569
1570 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1571 {
1572         STATS(jniinvokation();)
1573         return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
1574 }
1575
1576
1577 jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1578 {
1579         STATS(jniinvokation();)
1580         log_text("JNI-Call: CallShortMethodA");
1581
1582         return 0;
1583 }
1584
1585
1586
1587 jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1588 {
1589         jint ret;
1590         va_list vaargs;
1591         STATS(jniinvokation();)
1592
1593         va_start(vaargs,methodID);
1594         ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
1595         va_end(vaargs);
1596
1597         return ret;
1598 }
1599
1600
1601 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1602 {
1603         STATS(jniinvokation();)
1604         return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
1605 }
1606
1607
1608 jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1609 {
1610         STATS(jniinvokation();)
1611         log_text("JNI-Call: CallIntMethodA");
1612
1613         return 0;
1614 }
1615
1616
1617
1618 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1619 {
1620         jlong ret;
1621         va_list vaargs;
1622         STATS(jniinvokation();)
1623         
1624         va_start(vaargs,methodID);
1625         ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
1626         va_end(vaargs);
1627
1628         return ret;
1629 }
1630
1631
1632 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1633 {
1634         STATS(jniinvokation();)
1635         return  callLongMethod(obj,get_virtual(obj, methodID),args);
1636 }
1637
1638
1639 jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1640 {
1641         STATS(jniinvokation();)
1642         log_text("JNI-Call: CallLongMethodA");
1643
1644         return 0;
1645 }
1646
1647
1648
1649 jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1650 {
1651         jfloat ret;
1652         va_list vaargs;
1653
1654         STATS(jniinvokation();)
1655 /*      log_text("JNI-Call: CallFloatMethod");*/
1656
1657         va_start(vaargs,methodID);
1658         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
1659         va_end(vaargs);
1660
1661         return ret;
1662 }
1663
1664
1665 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1666 {
1667         STATS(jniinvokation();)
1668         log_text("JNI-Call: CallFloatMethodV");
1669         return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
1670 }
1671
1672
1673 jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1674 {
1675         STATS(jniinvokation();)
1676         log_text("JNI-Call: CallFloatMethodA");
1677
1678         return 0;
1679 }
1680
1681
1682
1683 jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1684 {
1685         jdouble ret;
1686         va_list vaargs;
1687         STATS(jniinvokation();)
1688
1689 /*      log_text("JNI-Call: CallDoubleMethod");*/
1690
1691         va_start(vaargs,methodID);
1692         ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
1693         va_end(vaargs);
1694
1695         return ret;
1696 }
1697
1698
1699 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1700 {
1701         STATS(jniinvokation();)
1702         log_text("JNI-Call: CallDoubleMethodV");
1703         return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
1704 }
1705
1706
1707 jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
1708 {
1709         STATS(jniinvokation();)
1710         log_text("JNI-Call: CallDoubleMethodA");
1711         return 0;
1712 }
1713
1714
1715
1716 void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1717 {
1718         va_list vaargs;
1719         STATS(jniinvokation();)
1720
1721         va_start(vaargs,methodID);
1722         (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
1723         va_end(vaargs);
1724 }
1725
1726
1727 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
1728 {
1729         log_text("JNI-Call: CallVoidMethodV");
1730         STATS(jniinvokation();)
1731         (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
1732 }
1733
1734
1735 void CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
1736 {
1737         STATS(jniinvokation();)
1738         log_text("JNI-Call: CallVoidMethodA");
1739 }
1740
1741
1742
1743 jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1744 {
1745         STATS(jniinvokation();)
1746
1747         log_text("JNI-Call: CallNonvirtualObjectMethod: IMPLEMENT ME!");
1748
1749         return NewLocalRef(env, NULL);
1750 }
1751
1752
1753 jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1754 {
1755         STATS(jniinvokation();)
1756
1757         log_text("JNI-Call: CallNonvirtualObjectMethodV: IMPLEMENT ME!");
1758
1759         return NewLocalRef(env, NULL);
1760 }
1761
1762
1763 jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1764 {
1765         STATS(jniinvokation();)
1766
1767         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1768
1769         return NewLocalRef(env, NULL);
1770 }
1771
1772
1773
1774 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1775 {
1776         jboolean ret;
1777         va_list vaargs;
1778         STATS(jniinvokation();)
1779
1780 /*      log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
1781
1782         va_start(vaargs,methodID);
1783         ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
1784         va_end(vaargs);
1785         return ret;
1786
1787 }
1788
1789
1790 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1791 {
1792         STATS(jniinvokation();)
1793 /*      log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
1794         return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
1795 }
1796
1797
1798 jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
1799 {
1800         STATS(jniinvokation();)
1801         log_text("JNI-Call: CallNonvirtualBooleanMethodA");
1802
1803         return 0;
1804 }
1805
1806
1807
1808 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1809 {
1810         jbyte ret;
1811         va_list vaargs;
1812
1813         STATS(jniinvokation();)
1814 /*      log_text("JNI-Call: CallNonvirutalByteMethod");*/
1815
1816         va_start(vaargs,methodID);
1817         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
1818         va_end(vaargs);
1819         return ret;
1820 }
1821
1822
1823 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1824 {
1825         STATS(jniinvokation();)
1826         /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
1827         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
1828
1829 }
1830
1831
1832 jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1833 {
1834         STATS(jniinvokation();)
1835         log_text("JNI-Call: CallNonvirtualByteMethodA");
1836
1837         return 0;
1838 }
1839
1840
1841
1842 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1843 {
1844         jchar ret;
1845         va_list vaargs;
1846
1847         STATS(jniinvokation();)
1848 /*      log_text("JNI-Call: CallNonVirtualCharMethod");*/
1849
1850         va_start(vaargs,methodID);
1851         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
1852         va_end(vaargs);
1853         return ret;
1854 }
1855
1856
1857 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1858 {
1859         STATS(jniinvokation();)
1860         /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
1861         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
1862 }
1863
1864
1865 jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1866 {
1867         STATS(jniinvokation();)
1868         log_text("JNI-Call: CallNonvirtualCharMethodA");
1869
1870         return 0;
1871 }
1872
1873
1874
1875 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1876 {
1877         jshort ret;
1878         va_list vaargs;
1879         STATS(jniinvokation();)
1880
1881         /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
1882
1883         va_start(vaargs,methodID);
1884         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
1885         va_end(vaargs);
1886         return ret;
1887 }
1888
1889
1890 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1891 {
1892         STATS(jniinvokation();)
1893         /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
1894         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
1895 }
1896
1897
1898 jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1899 {
1900         STATS(jniinvokation();)
1901         log_text("JNI-Call: CallNonvirtualShortMethodA");
1902
1903         return 0;
1904 }
1905
1906
1907
1908 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1909 {
1910
1911         jint ret;
1912         va_list vaargs;
1913         STATS(jniinvokation();)
1914
1915         /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
1916
1917         va_start(vaargs,methodID);
1918         ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
1919         va_end(vaargs);
1920         return ret;
1921 }
1922
1923
1924 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1925 {
1926         STATS(jniinvokation();)
1927         /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
1928         return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
1929 }
1930
1931
1932 jint CallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1933 {
1934         STATS(jniinvokation();)
1935         log_text("JNI-Call: CallNonvirtualIntMethodA");
1936
1937         return 0;
1938 }
1939
1940
1941
1942 jlong CallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1943 {
1944         STATS(jniinvokation();)
1945         log_text("JNI-Call: CallNonvirtualLongMethod");
1946
1947         return 0;
1948 }
1949
1950
1951 jlong CallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1952 {
1953         STATS(jniinvokation();)
1954         log_text("JNI-Call: CallNonvirtualLongMethodV");
1955
1956         return 0;
1957 }
1958
1959
1960 jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1961 {
1962         STATS(jniinvokation();)
1963         log_text("JNI-Call: CallNonvirtualLongMethodA");
1964
1965         return 0;
1966 }
1967
1968
1969
1970 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
1971 {
1972         jfloat ret;
1973         va_list vaargs;
1974         STATS(jniinvokation();)
1975
1976         /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
1977
1978
1979         va_start(vaargs,methodID);
1980         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
1981         va_end(vaargs);
1982         return ret;
1983
1984 }
1985
1986
1987 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
1988 {
1989         STATS(jniinvokation();)
1990         log_text("JNI-Call: CallNonvirtualFloatMethodV");
1991         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
1992 }
1993
1994
1995 jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
1996 {
1997         STATS(jniinvokation();)
1998         log_text("JNI-Call: CallNonvirtualFloatMethodA");
1999
2000         return 0;
2001 }
2002
2003
2004
2005 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2006 {
2007         jdouble ret;
2008         va_list vaargs;
2009         STATS(jniinvokation();)
2010         log_text("JNI-Call: CallNonvirtualDoubleMethod");
2011
2012         va_start(vaargs,methodID);
2013         ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
2014         va_end(vaargs);
2015         return ret;
2016
2017 }
2018
2019
2020 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2021 {
2022         STATS(jniinvokation();)
2023 /*      log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
2024         return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
2025 }
2026
2027
2028 jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
2029 {
2030         STATS(jniinvokation();)
2031         log_text("JNI-Call: CallNonvirtualDoubleMethodA");
2032
2033         return 0;
2034 }
2035
2036
2037
2038 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
2039 {
2040         va_list vaargs;
2041         STATS(jniinvokation();)
2042
2043 /*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
2044
2045         va_start(vaargs,methodID);
2046         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
2047         va_end(vaargs);
2048
2049 }
2050
2051
2052 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
2053 {
2054 /*      log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
2055         STATS(jniinvokation();)
2056
2057         (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
2058
2059 }
2060
2061
2062 void CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
2063 {
2064         STATS(jniinvokation();)
2065         log_text("JNI-Call: CallNonvirtualVoidMethodA");
2066 }
2067
2068 /************************* JNI-functions for accessing fields ************************/
2069
2070 jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig) 
2071 {
2072         jfieldID f;
2073
2074         STATS(jniinvokation();)
2075
2076         f = class_findfield(clazz, utf_new_char((char *) name), utf_new_char((char *) sig)); 
2077         
2078         if (!f)
2079                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
2080
2081         return f;
2082 }
2083
2084 /*************************** retrieve fieldid, abort on error ************************/
2085
2086 jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
2087 {
2088     jfieldID id = GetFieldID(env, clazz, name, sig);
2089         STATS(jniinvokation();)
2090
2091     if (!id) {
2092        log_text("class:");
2093        utf_display(clazz->name);
2094        log_text("\nfield:");
2095        log_text(name);
2096        log_text("sig:");
2097        log_text(sig);
2098
2099        log_text("setfield_critical failed");
2100            assert(0);
2101     }
2102     return id;
2103 }
2104
2105 jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2106 {
2107         java_objectheader *o;
2108
2109         STATS(jniinvokation();)
2110
2111         o = getField(obj, java_objectheader*, fieldID);
2112
2113         return NewLocalRef(env, o);
2114 }
2115
2116 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
2117 {
2118         STATS(jniinvokation();)
2119         return getField(obj,jboolean,fieldID);
2120 }
2121
2122
2123 jbyte GetByteField (JNIEnv *env, jobject obj, jfieldID fieldID)
2124 {
2125         STATS(jniinvokation();)
2126         return getField(obj,jbyte,fieldID);
2127 }
2128
2129
2130 jchar GetCharField (JNIEnv *env, jobject obj, jfieldID fieldID)
2131 {
2132         STATS(jniinvokation();)
2133         return getField(obj,jchar,fieldID);
2134 }
2135
2136
2137 jshort GetShortField (JNIEnv *env, jobject obj, jfieldID fieldID)
2138 {
2139         STATS(jniinvokation();)
2140         return getField(obj,jshort,fieldID);
2141 }
2142
2143
2144 jint GetIntField (JNIEnv *env, jobject obj, jfieldID fieldID)
2145 {
2146         STATS(jniinvokation();)
2147         return getField(obj,jint,fieldID);
2148 }
2149
2150
2151 jlong GetLongField (JNIEnv *env, jobject obj, jfieldID fieldID)
2152 {
2153         STATS(jniinvokation();)
2154         return getField(obj,jlong,fieldID);
2155 }
2156
2157
2158 jfloat GetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID)
2159 {
2160         STATS(jniinvokation();)
2161         return getField(obj,jfloat,fieldID);
2162 }
2163
2164
2165 jdouble GetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID)
2166 {
2167         STATS(jniinvokation();)
2168         return getField(obj,jdouble,fieldID);
2169 }
2170
2171 void SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
2172 {
2173         STATS(jniinvokation();)
2174         setField(obj,jobject,fieldID,val);
2175 }
2176
2177
2178 void SetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val)
2179 {
2180         STATS(jniinvokation();)
2181         setField(obj,jboolean,fieldID,val);
2182 }
2183
2184
2185 void SetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val)
2186 {
2187         STATS(jniinvokation();)
2188         setField(obj,jbyte,fieldID,val);
2189 }
2190
2191
2192 void SetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val)
2193 {
2194         STATS(jniinvokation();)
2195         setField(obj,jchar,fieldID,val);
2196 }
2197
2198
2199 void SetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val)
2200 {
2201         STATS(jniinvokation();)
2202         setField(obj,jshort,fieldID,val);
2203 }
2204
2205
2206 void SetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val)
2207 {
2208         STATS(jniinvokation();)
2209         setField(obj,jint,fieldID,val);
2210 }
2211
2212
2213 void SetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val)
2214 {
2215         STATS(jniinvokation();)
2216         setField(obj,jlong,fieldID,val);
2217 }
2218
2219
2220 void SetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val)
2221 {
2222         STATS(jniinvokation();)
2223         setField(obj,jfloat,fieldID,val);
2224 }
2225
2226
2227 void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
2228 {
2229         STATS(jniinvokation();)
2230         setField(obj,jdouble,fieldID,val);
2231 }
2232
2233
2234 /**************** JNI-functions for calling static methods **********************/ 
2235
2236 jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2237 {
2238         jmethodID m;
2239         STATS(jniinvokation();)
2240
2241         m = class_resolvemethod(clazz,
2242                                                         utf_new_char((char *) name),
2243                                                         utf_new_char((char *) sig));
2244
2245         if (!m || !(m->flags & ACC_STATIC)) {
2246                 *exceptionptr =
2247                         new_exception_message(string_java_lang_NoSuchMethodError, name);
2248
2249                 return NULL;
2250         }
2251
2252         return m;
2253 }
2254
2255
2256 jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2257 {
2258         java_objectheader *ret;
2259         va_list            vaargs;
2260
2261         STATS(jniinvokation();)
2262
2263         va_start(vaargs, methodID);
2264         ret = callObjectMethod(0, methodID, vaargs);
2265         va_end(vaargs);
2266
2267         return NewLocalRef(env, ret);
2268 }
2269
2270
2271 jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2272 {
2273         java_objectheader *ret;
2274
2275         STATS(jniinvokation();)
2276         
2277         ret = callObjectMethod(0, methodID, args);
2278
2279         return NewLocalRef(env, ret);
2280 }
2281
2282
2283 jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2284 {
2285         STATS(jniinvokation();)
2286
2287         log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
2288
2289         return NewLocalRef(env, NULL);
2290 }
2291
2292
2293 jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2294 {
2295         jboolean ret;
2296         va_list vaargs;
2297         STATS(jniinvokation();)
2298
2299         va_start(vaargs, methodID);
2300         ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
2301         va_end(vaargs);
2302
2303         return ret;
2304 }
2305
2306
2307 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2308 {
2309         STATS(jniinvokation();)
2310         return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
2311 }
2312
2313
2314 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2315 {
2316         STATS(jniinvokation();)
2317         log_text("JNI-Call: CallStaticBooleanMethodA");
2318
2319         return 0;
2320 }
2321
2322
2323 jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2324 {
2325         jbyte ret;
2326         va_list vaargs;
2327         STATS(jniinvokation();)
2328
2329         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2330
2331         va_start(vaargs, methodID);
2332         ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
2333         va_end(vaargs);
2334
2335         return ret;
2336 }
2337
2338
2339 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2340 {
2341         STATS(jniinvokation();)
2342         return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
2343 }
2344
2345
2346 jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2347 {
2348         STATS(jniinvokation();)
2349         log_text("JNI-Call: CallStaticByteMethodA");
2350
2351         return 0;
2352 }
2353
2354
2355 jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2356 {
2357         jchar ret;
2358         va_list vaargs;
2359         STATS(jniinvokation();)
2360
2361         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2362
2363         va_start(vaargs, methodID);
2364         ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
2365         va_end(vaargs);
2366
2367         return ret;
2368 }
2369
2370
2371 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2372 {
2373         STATS(jniinvokation();)
2374         return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
2375 }
2376
2377
2378 jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2379 {
2380         STATS(jniinvokation();)
2381         log_text("JNI-Call: CallStaticCharMethodA");
2382
2383         return 0;
2384 }
2385
2386
2387
2388 jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2389 {
2390         jshort ret;
2391         va_list vaargs;
2392         STATS(jniinvokation();)
2393
2394         /*      log_text("JNI-Call: CallStaticByteMethod");*/
2395
2396         va_start(vaargs, methodID);
2397         ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
2398         va_end(vaargs);
2399
2400         return ret;
2401 }
2402
2403
2404 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2405 {
2406         STATS(jniinvokation();)
2407         /*log_text("JNI-Call: CallStaticShortMethodV");*/
2408         return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
2409 }
2410
2411
2412 jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2413 {
2414         STATS(jniinvokation();)
2415         log_text("JNI-Call: CallStaticShortMethodA");
2416
2417         return 0;
2418 }
2419
2420
2421
2422 jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2423 {
2424         jint ret;
2425         va_list vaargs;
2426         STATS(jniinvokation();)
2427
2428         /*      log_text("JNI-Call: CallStaticIntMethod");*/
2429
2430         va_start(vaargs, methodID);
2431         ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
2432         va_end(vaargs);
2433
2434         return ret;
2435 }
2436
2437
2438 jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2439 {
2440         STATS(jniinvokation();)
2441         log_text("JNI-Call: CallStaticIntMethodV");
2442
2443         return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
2444 }
2445
2446
2447 jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2448 {
2449         STATS(jniinvokation();)
2450         log_text("JNI-Call: CallStaticIntMethodA");
2451
2452         return 0;
2453 }
2454
2455
2456
2457 jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2458 {
2459         jlong ret;
2460         va_list vaargs;
2461         STATS(jniinvokation();)
2462
2463         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2464
2465         va_start(vaargs, methodID);
2466         ret = callLongMethod(0, methodID, vaargs);
2467         va_end(vaargs);
2468
2469         return ret;
2470 }
2471
2472
2473 jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
2474                                                         va_list args)
2475 {
2476         STATS(jniinvokation();)
2477         
2478         return callLongMethod(0, methodID, args);
2479 }
2480
2481
2482 jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2483 {
2484         STATS(jniinvokation();)
2485
2486         log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!!!");
2487
2488         return 0;
2489 }
2490
2491
2492
2493 jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2494 {
2495         jfloat ret;
2496         va_list vaargs;
2497         STATS(jniinvokation();)
2498
2499         /*      log_text("JNI-Call: CallStaticLongMethod");*/
2500
2501         va_start(vaargs, methodID);
2502         ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
2503         va_end(vaargs);
2504
2505         return ret;
2506 }
2507
2508
2509 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2510 {
2511         STATS(jniinvokation();)
2512
2513         return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
2514
2515 }
2516
2517
2518 jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2519 {
2520         STATS(jniinvokation();)
2521         log_text("JNI-Call: CallStaticFloatMethodA");
2522
2523         return 0;
2524 }
2525
2526
2527
2528 jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
2529 {
2530         jdouble ret;
2531         va_list vaargs;
2532         STATS(jniinvokation();)
2533
2534         /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
2535
2536         va_start(vaargs,methodID);
2537         ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
2538         va_end(vaargs);
2539
2540         return ret;
2541 }
2542
2543
2544 jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
2545 {
2546         STATS(jniinvokation();)
2547         log_text("JNI-Call: CallStaticDoubleMethodV");
2548
2549         return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
2550 }
2551
2552
2553 jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
2554 {
2555         STATS(jniinvokation();)
2556         log_text("JNI-Call: CallStaticDoubleMethodA");
2557
2558         return 0;
2559 }
2560
2561
2562 void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
2563 {
2564         va_list vaargs;
2565         STATS(jniinvokation();)
2566
2567         va_start(vaargs, methodID);
2568         (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
2569         va_end(vaargs);
2570 }
2571
2572
2573 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
2574 {
2575         log_text("JNI-Call: CallStaticVoidMethodV");
2576         STATS(jniinvokation();)
2577         (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
2578 }
2579
2580
2581 void CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args)
2582 {
2583         STATS(jniinvokation();)
2584         log_text("JNI-Call: CallStaticVoidMethodA");
2585 }
2586
2587
2588 /* Accessing Static Fields ****************************************************/
2589
2590 /* GetStaticFieldID ************************************************************
2591
2592    Returns the field ID for a static field of a class. The field is
2593    specified by its name and signature. The GetStatic<type>Field and
2594    SetStatic<type>Field families of accessor functions use field IDs
2595    to retrieve static fields.
2596
2597 *******************************************************************************/
2598
2599 jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
2600 {
2601         jfieldID f;
2602         STATS(jniinvokation();)
2603
2604         f = class_findfield(clazz,
2605                                                 utf_new_char((char *) name),
2606                                                 utf_new_char((char *) sig));
2607         
2608         if (!f)
2609                 *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
2610
2611         return f;
2612 }
2613
2614
2615 /* GetStatic<type>Field ********************************************************
2616
2617    This family of accessor routines returns the value of a static
2618    field of an object.
2619
2620 *******************************************************************************/
2621
2622 jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2623 {
2624         STATS(jniinvokation();)
2625
2626         if (!clazz->initialized)
2627                 if (!initialize_class(clazz))
2628                         return NULL;
2629
2630         return NewLocalRef(env, fieldID->value.a);
2631 }
2632
2633
2634 jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2635 {
2636         STATS(jniinvokation();)
2637
2638         if (!clazz->initialized)
2639                 if (!initialize_class(clazz))
2640                         return false;
2641
2642         return fieldID->value.i;       
2643 }
2644
2645
2646 jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2647 {
2648         STATS(jniinvokation();)
2649
2650         if (!clazz->initialized)
2651                 if (!initialize_class(clazz))
2652                         return 0;
2653
2654         return fieldID->value.i;       
2655 }
2656
2657
2658 jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2659 {
2660         STATS(jniinvokation();)
2661
2662         if (!clazz->initialized)
2663                 if (!initialize_class(clazz))
2664                         return 0;
2665
2666         return fieldID->value.i;       
2667 }
2668
2669
2670 jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2671 {
2672         STATS(jniinvokation();)
2673
2674         if (!clazz->initialized)
2675                 if (!initialize_class(clazz))
2676                         return 0;
2677
2678         return fieldID->value.i;       
2679 }
2680
2681
2682 jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2683 {
2684         STATS(jniinvokation();)
2685
2686         if (!clazz->initialized)
2687                 if (!initialize_class(clazz))
2688                         return 0;
2689
2690         return fieldID->value.i;       
2691 }
2692
2693
2694 jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2695 {
2696         STATS(jniinvokation();)
2697
2698         if (!clazz->initialized)
2699                 if (!initialize_class(clazz))
2700                         return 0;
2701
2702         return fieldID->value.l;
2703 }
2704
2705
2706 jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2707 {
2708         STATS(jniinvokation();)
2709
2710         if (!clazz->initialized)
2711                 if (!initialize_class(clazz))
2712                         return 0.0;
2713
2714         return fieldID->value.f;
2715 }
2716
2717
2718 jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
2719 {
2720         STATS(jniinvokation();)
2721
2722         if (!clazz->initialized)
2723                 if (!initialize_class(clazz))
2724                         return 0.0;
2725
2726         return fieldID->value.d;
2727 }
2728
2729
2730 /*  SetStatic<type>Field *******************************************************
2731
2732         This family of accessor routines sets the value of a static field
2733         of an object.
2734
2735 *******************************************************************************/
2736
2737 void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
2738 {
2739         STATS(jniinvokation();)
2740
2741         if (!clazz->initialized)
2742                 if (!initialize_class(clazz))
2743                         return;
2744
2745         fieldID->value.a = value;
2746 }
2747
2748
2749 void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
2750 {
2751         STATS(jniinvokation();)
2752
2753         if (!clazz->initialized)
2754                 if (!initialize_class(clazz))
2755                         return;
2756
2757         fieldID->value.i = value;
2758 }
2759
2760
2761 void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
2762 {
2763         STATS(jniinvokation();)
2764
2765         if (!clazz->initialized)
2766                 if (!initialize_class(clazz))
2767                         return;
2768
2769         fieldID->value.i = value;
2770 }
2771
2772
2773 void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
2774 {
2775         STATS(jniinvokation();)
2776
2777         if (!clazz->initialized)
2778                 if (!initialize_class(clazz))
2779                         return;
2780
2781         fieldID->value.i = value;
2782 }
2783
2784
2785 void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
2786 {
2787         STATS(jniinvokation();)
2788
2789         if (!clazz->initialized)
2790                 if (!initialize_class(clazz))
2791                         return;
2792
2793         fieldID->value.i = value;
2794 }
2795
2796
2797 void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
2798 {
2799         STATS(jniinvokation();)
2800
2801         if (!clazz->initialized)
2802                 if (!initialize_class(clazz))
2803                         return;
2804
2805         fieldID->value.i = value;
2806 }
2807
2808
2809 void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
2810 {
2811         STATS(jniinvokation();)
2812
2813         if (!clazz->initialized)
2814                 if (!initialize_class(clazz))
2815                         return;
2816
2817         fieldID->value.l = value;
2818 }
2819
2820
2821 void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
2822 {
2823         STATS(jniinvokation();)
2824
2825         if (!clazz->initialized)
2826                 if (!initialize_class(clazz))
2827                         return;
2828
2829         fieldID->value.f = value;
2830 }
2831
2832
2833 void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
2834 {
2835         STATS(jniinvokation();)
2836
2837         if (!clazz->initialized)
2838                 if (!initialize_class(clazz))
2839                         return;
2840
2841         fieldID->value.d = value;
2842 }
2843
2844
2845 /* String Operations **********************************************************/
2846
2847 /* NewString *******************************************************************
2848
2849    Create new java.lang.String object from an array of Unicode
2850    characters.
2851
2852 *******************************************************************************/
2853
2854 jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
2855 {
2856         java_lang_String *s;
2857         java_chararray   *a;
2858         u4                i;
2859
2860         STATS(jniinvokation();)
2861         
2862         s = (java_lang_String *) builtin_new(class_java_lang_String);
2863         a = builtin_newarray_char(len);
2864
2865         /* javastring or characterarray could not be created */
2866         if (!a || !s)
2867                 return NULL;
2868
2869         /* copy text */
2870         for (i = 0; i < len; i++)
2871                 a->data[i] = buf[i];
2872
2873         s->value = a;
2874         s->offset = 0;
2875         s->count = len;
2876
2877         return (jstring) NewLocalRef(env, (jobject) s);
2878 }
2879
2880
2881 static jchar emptyStringJ[]={0,0};
2882
2883 /* GetStringLength *************************************************************
2884
2885    Returns the length (the count of Unicode characters) of a Java
2886    string.
2887
2888 *******************************************************************************/
2889
2890 jsize GetStringLength(JNIEnv *env, jstring str)
2891 {
2892         return ((java_lang_String *) str)->count;
2893 }
2894
2895
2896 /********************  convertes javastring to u2-array ****************************/
2897         
2898 u2 *javastring_tou2(jstring so) 
2899 {
2900         java_lang_String *s;
2901         java_chararray   *a;
2902         u2               *stringbuffer;
2903         u4                i;
2904
2905         STATS(jniinvokation();)
2906         
2907         s = (java_lang_String *) so;
2908
2909         if (!s)
2910                 return NULL;
2911
2912         a = s->value;
2913
2914         if (!a)
2915                 return NULL;
2916
2917         /* allocate memory */
2918
2919         stringbuffer = MNEW(u2, s->count + 1);
2920
2921         /* copy text */
2922
2923         for (i = 0; i < s->count; i++)
2924                 stringbuffer[i] = a->data[s->offset + i];
2925         
2926         /* terminate string */
2927
2928         stringbuffer[i] = '\0';
2929
2930         return stringbuffer;
2931 }
2932
2933
2934 /* GetStringChars **************************************************************
2935
2936    Returns a pointer to the array of Unicode characters of the
2937    string. This pointer is valid until ReleaseStringchars() is called.
2938
2939 *******************************************************************************/
2940
2941 const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2942 {       
2943         jchar *jc;
2944
2945         STATS(jniinvokation();)
2946
2947         jc = javastring_tou2(str);
2948
2949         if (jc) {
2950                 if (isCopy)
2951                         *isCopy = JNI_TRUE;
2952
2953                 return jc;
2954         }
2955
2956         if (isCopy)
2957                 *isCopy = JNI_TRUE;
2958
2959         return emptyStringJ;
2960 }
2961
2962
2963 /* ReleaseStringChars **********************************************************
2964
2965    Informs the VM that the native code no longer needs access to
2966    chars. The chars argument is a pointer obtained from string using
2967    GetStringChars().
2968
2969 *******************************************************************************/
2970
2971 void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2972 {
2973         STATS(jniinvokation();)
2974
2975         if (chars == emptyStringJ)
2976                 return;
2977
2978         MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
2979 }
2980
2981
2982 /* NewStringUTF ****************************************************************
2983
2984    Constructs a new java.lang.String object from an array of UTF-8 characters.
2985
2986 *******************************************************************************/
2987
2988 jstring NewStringUTF(JNIEnv *env, const char *bytes)
2989 {
2990         java_lang_String *s;
2991
2992         STATS(jniinvokation();)
2993
2994         s = javastring_new(utf_new_char(bytes));
2995
2996     return (jstring) NewLocalRef(env, (jobject) s);
2997 }
2998
2999
3000 /****************** returns the utf8 length in bytes of a string *******************/
3001
3002 jsize GetStringUTFLength (JNIEnv *env, jstring string)
3003 {   
3004     java_lang_String *s = (java_lang_String*) string;
3005         STATS(jniinvokation();)
3006
3007     return (jsize) u2_utflength(s->value->data, s->count); 
3008 }
3009
3010
3011 /* GetStringUTFChars ***********************************************************
3012
3013    Returns a pointer to an array of UTF-8 characters of the
3014    string. This array is valid until it is released by
3015    ReleaseStringUTFChars().
3016
3017 *******************************************************************************/
3018
3019 const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
3020 {
3021         utf *u;
3022         STATS(jniinvokation();)
3023
3024         if (!string)
3025                 return "";
3026
3027         if (isCopy)
3028                 *isCopy = JNI_TRUE;
3029         
3030         u = javastring_toutf((java_lang_String *) string, false);
3031
3032         if (u)
3033                 return u->text;
3034
3035         return "";
3036 }
3037
3038
3039 /* ReleaseStringUTFChars *******************************************************
3040
3041    Informs the VM that the native code no longer needs access to
3042    utf. The utf argument is a pointer derived from string using
3043    GetStringUTFChars().
3044
3045 *******************************************************************************/
3046
3047 void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
3048 {
3049         STATS(jniinvokation();)
3050
3051     /* XXX we don't release utf chars right now, perhaps that should be done 
3052            later. Since there is always one reference the garbage collector will
3053            never get them */
3054 }
3055
3056
3057 /* Array Operations ***********************************************************/
3058
3059 /* GetArrayLength **************************************************************
3060
3061    Returns the number of elements in the array.
3062
3063 *******************************************************************************/
3064
3065 jsize GetArrayLength(JNIEnv *env, jarray array)
3066 {
3067         STATS(jniinvokation();)
3068
3069         return array->size;
3070 }
3071
3072
3073 /* NewObjectArray **************************************************************
3074
3075    Constructs a new array holding objects in class elementClass. All
3076    elements are initially set to initialElement.
3077
3078 *******************************************************************************/
3079
3080 jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
3081 {
3082         java_objectarray *oa;
3083         s4                i;
3084
3085         STATS(jniinvokation();)
3086
3087         if (length < 0) {
3088                 *exceptionptr = new_negativearraysizeexception();
3089                 return NULL;
3090         }
3091
3092     oa = builtin_anewarray(length, elementClass);
3093
3094         if (!oa)
3095                 return NULL;
3096
3097         /* set all elements to initialElement */
3098
3099         for (i = 0; i < length; i++)
3100                 oa->data[i] = initialElement;
3101
3102         return (jobjectArray) NewLocalRef(env, (jobject) oa);
3103 }
3104
3105
3106 jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
3107 {
3108     jobject o;
3109
3110         STATS(jniinvokation();)
3111
3112         if (index >= array->header.size) {
3113                 *exceptionptr =
3114                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3115                 return NULL;
3116         }
3117
3118         o = array->data[index];
3119     
3120     return NewLocalRef(env, o);
3121 }
3122
3123
3124 void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
3125 {
3126         STATS(jniinvokation();)
3127     if (index >= array->header.size)
3128                 *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3129
3130     else {
3131                 /* check if the class of value is a subclass of the element class of the array */
3132                 if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
3133                         *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
3134
3135                 else
3136                         array->data[index] = val;
3137     }
3138 }
3139
3140
3141 jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
3142 {
3143         java_booleanarray *ba;
3144
3145         STATS(jniinvokation();)
3146
3147         if (len < 0) {
3148                 *exceptionptr = new_negativearraysizeexception();
3149                 return NULL;
3150         }
3151
3152         ba = builtin_newarray_boolean(len);
3153
3154         return (jbooleanArray) NewLocalRef(env, (jobject) ba);
3155 }
3156
3157
3158 jbyteArray NewByteArray(JNIEnv *env, jsize len)
3159 {
3160         java_bytearray *ba;
3161
3162         STATS(jniinvokation();)
3163
3164         if (len < 0) {
3165                 *exceptionptr = new_negativearraysizeexception();
3166                 return NULL;
3167         }
3168
3169         ba = builtin_newarray_byte(len);
3170
3171         return (jbyteArray) NewLocalRef(env, (jobject) ba);
3172 }
3173
3174
3175 jcharArray NewCharArray(JNIEnv *env, jsize len)
3176 {
3177         java_chararray *ca;
3178
3179         STATS(jniinvokation();)
3180
3181         if (len < 0) {
3182                 *exceptionptr = new_negativearraysizeexception();
3183                 return NULL;
3184         }
3185
3186         ca = builtin_newarray_char(len);
3187
3188         return (jcharArray) NewLocalRef(env, (jobject) ca);
3189 }
3190
3191
3192 jshortArray NewShortArray(JNIEnv *env, jsize len)
3193 {
3194         java_shortarray *sa;
3195
3196         STATS(jniinvokation();)
3197
3198         if (len < 0) {
3199                 *exceptionptr = new_negativearraysizeexception();
3200                 return NULL;
3201         }
3202
3203         sa = builtin_newarray_short(len);
3204
3205         return (jshortArray) NewLocalRef(env, (jobject) sa);
3206 }
3207
3208
3209 jintArray NewIntArray(JNIEnv *env, jsize len)
3210 {
3211         java_intarray *ia;
3212
3213         STATS(jniinvokation();)
3214
3215         if (len < 0) {
3216                 *exceptionptr = new_negativearraysizeexception();
3217                 return NULL;
3218         }
3219
3220         ia = builtin_newarray_int(len);
3221
3222         return (jintArray) NewLocalRef(env, (jobject) ia);
3223 }
3224
3225
3226 jlongArray NewLongArray(JNIEnv *env, jsize len)
3227 {
3228         java_longarray *la;
3229
3230         STATS(jniinvokation();)
3231
3232         if (len < 0) {
3233                 *exceptionptr = new_negativearraysizeexception();
3234                 return NULL;
3235         }
3236
3237         la = builtin_newarray_long(len);
3238
3239         return (jlongArray) NewLocalRef(env, (jobject) la);
3240 }
3241
3242
3243 jfloatArray NewFloatArray(JNIEnv *env, jsize len)
3244 {
3245         java_floatarray *fa;
3246
3247         STATS(jniinvokation();)
3248
3249         if (len < 0) {
3250                 *exceptionptr = new_negativearraysizeexception();
3251                 return NULL;
3252         }
3253
3254         fa = builtin_newarray_float(len);
3255
3256         return (jfloatArray) NewLocalRef(env, (jobject) fa);
3257 }
3258
3259
3260 jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
3261 {
3262         java_doublearray *da;
3263
3264         STATS(jniinvokation();)
3265
3266         if (len < 0) {
3267                 *exceptionptr = new_negativearraysizeexception();
3268                 return NULL;
3269         }
3270
3271         da = builtin_newarray_double(len);
3272
3273         return (jdoubleArray) NewLocalRef(env, (jobject) da);
3274 }
3275
3276
3277 /* Get<PrimitiveType>ArrayElements *********************************************
3278
3279    A family of functions that returns the body of the primitive array.
3280
3281 *******************************************************************************/
3282
3283 jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3284                                                                   jboolean *isCopy)
3285 {
3286         STATS(jniinvokation();)
3287
3288     if (isCopy)
3289                 *isCopy = JNI_FALSE;
3290
3291     return array->data;
3292 }
3293
3294
3295 jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
3296 {
3297         STATS(jniinvokation();)
3298
3299     if (isCopy)
3300                 *isCopy = JNI_FALSE;
3301
3302     return array->data;
3303 }
3304
3305
3306 jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
3307 {
3308         STATS(jniinvokation();)
3309
3310     if (isCopy)
3311                 *isCopy = JNI_FALSE;
3312
3313     return array->data;
3314 }
3315
3316
3317 jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
3318 {
3319         STATS(jniinvokation();)
3320
3321     if (isCopy)
3322                 *isCopy = JNI_FALSE;
3323
3324     return array->data;
3325 }
3326
3327
3328 jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
3329 {
3330         STATS(jniinvokation();)
3331
3332     if (isCopy)
3333                 *isCopy = JNI_FALSE;
3334
3335     return array->data;
3336 }
3337
3338
3339 jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
3340 {
3341         STATS(jniinvokation();)
3342
3343     if (isCopy)
3344                 *isCopy = JNI_FALSE;
3345
3346     return array->data;
3347 }
3348
3349
3350 jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
3351 {
3352         STATS(jniinvokation();)
3353
3354     if (isCopy)
3355                 *isCopy = JNI_FALSE;
3356
3357     return array->data;
3358 }
3359
3360
3361 jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3362                                                                 jboolean *isCopy)
3363 {
3364         STATS(jniinvokation();)
3365
3366     if (isCopy)
3367                 *isCopy = JNI_FALSE;
3368
3369     return array->data;
3370 }
3371
3372
3373 /* Release<PrimitiveType>ArrayElements *****************************************
3374
3375    A family of functions that informs the VM that the native code no
3376    longer needs access to elems. The elems argument is a pointer
3377    derived from array using the corresponding
3378    Get<PrimitiveType>ArrayElements() function. If necessary, this
3379    function copies back all changes made to elems to the original
3380    array.
3381
3382 *******************************************************************************/
3383
3384 void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
3385                                                                  jboolean *elems, jint mode)
3386 {
3387         STATS(jniinvokation();)
3388
3389         if (elems != array->data) {
3390                 switch (mode) {
3391                 case JNI_COMMIT:
3392                         MCOPY(array->data, elems, jboolean, array->header.size);
3393                         break;
3394                 case 0:
3395                         MCOPY(array->data, elems, jboolean, array->header.size);
3396                         /* XXX TWISTI how should it be freed? */
3397                         break;
3398                 case JNI_ABORT:
3399                         /* XXX TWISTI how should it be freed? */
3400                         break;
3401                 }
3402         }
3403 }
3404
3405
3406 void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
3407                                                           jint mode)
3408 {
3409         STATS(jniinvokation();)
3410
3411         if (elems != array->data) {
3412                 switch (mode) {
3413                 case JNI_COMMIT:
3414                         MCOPY(array->data, elems, jboolean, array->header.size);
3415                         break;
3416                 case 0:
3417                         MCOPY(array->data, elems, jboolean, array->header.size);
3418                         /* XXX TWISTI how should it be freed? */
3419                         break;
3420                 case JNI_ABORT:
3421                         /* XXX TWISTI how should it be freed? */
3422                         break;
3423                 }
3424         }
3425 }
3426
3427
3428 void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
3429                                                           jint mode)
3430 {
3431         STATS(jniinvokation();)
3432
3433         if (elems != array->data) {
3434                 switch (mode) {
3435                 case JNI_COMMIT:
3436                         MCOPY(array->data, elems, jboolean, array->header.size);
3437                         break;
3438                 case 0:
3439                         MCOPY(array->data, elems, jboolean, array->header.size);
3440                         /* XXX TWISTI how should it be freed? */
3441                         break;
3442                 case JNI_ABORT:
3443                         /* XXX TWISTI how should it be freed? */
3444                         break;
3445                 }
3446         }
3447 }
3448
3449
3450 void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
3451                                                            jint mode)
3452 {
3453         STATS(jniinvokation();)
3454
3455         if (elems != array->data) {
3456                 switch (mode) {
3457                 case JNI_COMMIT:
3458                         MCOPY(array->data, elems, jboolean, array->header.size);
3459                         break;
3460                 case 0:
3461                         MCOPY(array->data, elems, jboolean, array->header.size);
3462                         /* XXX TWISTI how should it be freed? */
3463                         break;
3464                 case JNI_ABORT:
3465                         /* XXX TWISTI how should it be freed? */
3466                         break;
3467                 }
3468         }
3469 }
3470
3471
3472 void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
3473                                                          jint mode)
3474 {
3475         STATS(jniinvokation();)
3476
3477         if (elems != array->data) {
3478                 switch (mode) {
3479                 case JNI_COMMIT:
3480                         MCOPY(array->data, elems, jboolean, array->header.size);
3481                         break;
3482                 case 0:
3483                         MCOPY(array->data, elems, jboolean, array->header.size);
3484                         /* XXX TWISTI how should it be freed? */
3485                         break;
3486                 case JNI_ABORT:
3487                         /* XXX TWISTI how should it be freed? */
3488                         break;
3489                 }
3490         }
3491 }
3492
3493
3494 void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
3495                                                           jint mode)
3496 {
3497         STATS(jniinvokation();)
3498
3499         if (elems != array->data) {
3500                 switch (mode) {
3501                 case JNI_COMMIT:
3502                         MCOPY(array->data, elems, jboolean, array->header.size);
3503                         break;
3504                 case 0:
3505                         MCOPY(array->data, elems, jboolean, array->header.size);
3506                         /* XXX TWISTI how should it be freed? */
3507                         break;
3508                 case JNI_ABORT:
3509                         /* XXX TWISTI how should it be freed? */
3510                         break;
3511                 }
3512         }
3513 }
3514
3515
3516 void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
3517                                                            jint mode)
3518 {
3519         STATS(jniinvokation();)
3520
3521         if (elems != array->data) {
3522                 switch (mode) {
3523                 case JNI_COMMIT:
3524                         MCOPY(array->data, elems, jboolean, array->header.size);
3525                         break;
3526                 case 0:
3527                         MCOPY(array->data, elems, jboolean, array->header.size);
3528                         /* XXX TWISTI how should it be freed? */
3529                         break;
3530                 case JNI_ABORT:
3531                         /* XXX TWISTI how should it be freed? */
3532                         break;
3533                 }
3534         }
3535 }
3536
3537
3538 void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
3539                                                                 jdouble *elems, jint mode)
3540 {
3541         STATS(jniinvokation();)
3542
3543         if (elems != array->data) {
3544                 switch (mode) {
3545                 case JNI_COMMIT:
3546                         MCOPY(array->data, elems, jboolean, array->header.size);
3547                         break;
3548                 case 0:
3549                         MCOPY(array->data, elems, jboolean, array->header.size);
3550                         /* XXX TWISTI how should it be freed? */
3551                         break;
3552                 case JNI_ABORT:
3553                         /* XXX TWISTI how should it be freed? */
3554                         break;
3555                 }
3556         }
3557 }
3558
3559
3560 /*  Get<PrimitiveType>ArrayRegion **********************************************
3561
3562         A family of functions that copies a region of a primitive array
3563         into a buffer.
3564
3565 *******************************************************************************/
3566
3567 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3568                                                    jsize len, jboolean *buf)
3569 {
3570         STATS(jniinvokation();)
3571
3572     if (start < 0 || len < 0 || start + len > array->header.size)
3573                 *exceptionptr =
3574                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3575
3576     else
3577                 MCOPY(buf, &array->data[start], jboolean, len);
3578 }
3579
3580
3581 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3582                                                 jbyte *buf)
3583 {
3584         STATS(jniinvokation();)
3585
3586     if (start < 0 || len < 0 || start + len > array->header.size) 
3587                 *exceptionptr =
3588                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3589
3590     else
3591                 MCOPY(buf, &array->data[start], jbyte, len);
3592 }
3593
3594
3595 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3596                                                 jchar *buf)
3597 {
3598         STATS(jniinvokation();)
3599
3600     if (start < 0 || len < 0 || start + len > array->header.size)
3601                 *exceptionptr =
3602                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3603
3604     else
3605                 MCOPY(buf, &array->data[start], jchar, len);
3606 }
3607
3608
3609 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3610                                                  jsize len, jshort *buf)
3611 {
3612         STATS(jniinvokation();)
3613
3614     if (start < 0 || len < 0 || start + len > array->header.size)
3615                 *exceptionptr =
3616                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3617
3618     else        
3619                 MCOPY(buf, &array->data[start], jshort, len);
3620 }
3621
3622
3623 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3624                                            jint *buf)
3625 {
3626         STATS(jniinvokation();)
3627
3628     if (start < 0 || len < 0 || start + len > array->header.size)
3629                 *exceptionptr =
3630                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3631
3632     else
3633                 MCOPY(buf, &array->data[start], jint, len);
3634 }
3635
3636
3637 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
3638                                                 jlong *buf)
3639 {
3640         STATS(jniinvokation();)
3641
3642     if (start < 0 || len < 0 || start + len > array->header.size)
3643                 *exceptionptr =
3644                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3645
3646     else
3647                 MCOPY(buf, &array->data[start], jlong, len);
3648 }
3649
3650
3651 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3652                                                  jsize len, jfloat *buf)
3653 {
3654         STATS(jniinvokation();)
3655
3656     if (start < 0 || len < 0 || start + len > array->header.size)
3657                 *exceptionptr =
3658                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3659
3660     else
3661                 MCOPY(buf, &array->data[start], jfloat, len);
3662 }
3663
3664
3665 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3666                                                   jsize len, jdouble *buf)
3667 {
3668         STATS(jniinvokation();)
3669
3670     if (start < 0 || len < 0 || start+len>array->header.size)
3671                 *exceptionptr =
3672                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3673
3674     else
3675                 MCOPY(buf, &array->data[start], jdouble, len);
3676 }
3677
3678
3679 /*  Set<PrimitiveType>ArrayRegion **********************************************
3680
3681         A family of functions that copies back a region of a primitive
3682         array from a buffer.
3683
3684 *******************************************************************************/
3685
3686 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
3687                                                    jsize len, jboolean *buf)
3688 {
3689         STATS(jniinvokation();)
3690
3691     if (start < 0 || len < 0 || start + len > array->header.size)
3692                 *exceptionptr =
3693                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3694
3695     else
3696                 MCOPY(&array->data[start], buf, jboolean, len);
3697 }
3698
3699
3700 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
3701                                                 jbyte *buf)
3702 {
3703         STATS(jniinvokation();)
3704
3705     if (start < 0 || len < 0 || start + len > array->header.size)
3706                 *exceptionptr =
3707                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3708
3709     else
3710                 MCOPY(&array->data[start], buf, jbyte, len);
3711 }
3712
3713
3714 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
3715                                                 jchar *buf)
3716 {
3717         STATS(jniinvokation();)
3718
3719     if (start < 0 || len < 0 || start + len > array->header.size)
3720                 *exceptionptr =
3721                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3722
3723     else
3724                 MCOPY(&array->data[start], buf, jchar, len);
3725
3726 }
3727
3728
3729 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
3730                                                  jsize len, jshort *buf)
3731 {
3732         STATS(jniinvokation();)
3733
3734     if (start < 0 || len < 0 || start + len > array->header.size)
3735                 *exceptionptr =
3736                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3737
3738     else
3739                 MCOPY(&array->data[start], buf, jshort, len);
3740 }
3741
3742
3743 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
3744                                            jint *buf)
3745 {
3746         STATS(jniinvokation();)
3747
3748     if (start < 0 || len < 0 || start + len > array->header.size)
3749                 *exceptionptr =
3750                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3751
3752     else
3753                 MCOPY(&array->data[start], buf, jint, len);
3754
3755 }
3756
3757
3758 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
3759                                                 jlong *buf)
3760 {
3761         STATS(jniinvokation();)
3762
3763     if (start < 0 || len < 0 || start + len > array->header.size)
3764                 *exceptionptr =
3765                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3766
3767     else
3768                 MCOPY(&array->data[start], buf, jlong, len);
3769
3770 }
3771
3772
3773 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
3774                                                  jsize len, jfloat *buf)
3775 {
3776         STATS(jniinvokation();)
3777
3778     if (start < 0 || len < 0 || start + len > array->header.size)
3779                 *exceptionptr =
3780                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3781
3782     else
3783                 MCOPY(&array->data[start], buf, jfloat, len);
3784
3785 }
3786
3787
3788 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
3789                                                   jsize len, jdouble *buf)
3790 {
3791         STATS(jniinvokation();)
3792
3793     if (start < 0 || len < 0 || start + len > array->header.size)
3794                 *exceptionptr =
3795                         new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
3796
3797     else
3798                 MCOPY(&array->data[start], buf, jdouble, len);
3799 }
3800
3801
3802 /* Registering Native Methods *************************************************/
3803
3804 /* RegisterNatives *************************************************************
3805
3806    Registers native methods with the class specified by the clazz
3807    argument. The methods parameter specifies an array of
3808    JNINativeMethod structures that contain the names, signatures, and
3809    function pointers of the native methods. The nMethods parameter
3810    specifies the number of native methods in the array.
3811
3812 *******************************************************************************/
3813
3814 jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
3815                                          jint nMethods)
3816 {
3817         STATS(jniinvokation();)
3818
3819     log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
3820
3821     return 0;
3822 }
3823
3824
3825 /* UnregisterNatives ***********************************************************
3826
3827    Unregisters native methods of a class. The class goes back to the
3828    state before it was linked or registered with its native method
3829    functions.
3830
3831    This function should not be used in normal native code. Instead, it
3832    provides special programs a way to reload and relink native
3833    libraries.
3834
3835 *******************************************************************************/
3836
3837 jint UnregisterNatives(JNIEnv *env, jclass clazz)
3838 {
3839         STATS(jniinvokation();)
3840
3841         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3842
3843     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3844
3845     return 0;
3846 }
3847
3848
3849 /* Monitor Operations *********************************************************/
3850
3851 /* MonitorEnter ****************************************************************
3852
3853    Enters the monitor associated with the underlying Java object
3854    referred to by obj.
3855
3856 *******************************************************************************/
3857
3858 jint MonitorEnter(JNIEnv *env, jobject obj)
3859 {
3860         STATS(jniinvokation();)
3861
3862         if (!obj) {
3863                 *exceptionptr = new_nullpointerexception();
3864                 return JNI_ERR;
3865         }
3866
3867 #if defined(USE_THREADS)
3868         builtin_monitorenter(obj);
3869 #endif
3870
3871         return JNI_OK;
3872 }
3873
3874
3875 /* MonitorExit *****************************************************************
3876
3877    The current thread must be the owner of the monitor associated with
3878    the underlying Java object referred to by obj. The thread
3879    decrements the counter indicating the number of times it has
3880    entered this monitor. If the value of the counter becomes zero, the
3881    current thread releases the monitor.
3882
3883 *******************************************************************************/
3884
3885 jint MonitorExit(JNIEnv *env, jobject obj)
3886 {
3887         STATS(jniinvokation();)
3888         if (!obj) {
3889                 *exceptionptr = new_nullpointerexception();
3890                 return JNI_ERR;
3891         }
3892
3893 #if defined(USE_THREADS)
3894         builtin_monitorexit(obj);
3895 #endif
3896
3897         return JNI_OK;
3898 }
3899
3900
3901 /* JavaVM Interface ***********************************************************/
3902
3903 /* GetJavaVM *******************************************************************
3904
3905    Returns the Java VM interface (used in the Invocation API)
3906    associated with the current thread. The result is placed at the
3907    location pointed to by the second argument, vm.
3908
3909 *******************************************************************************/
3910
3911 jint GetJavaVM(JNIEnv *env, JavaVM **vm)
3912 {
3913         STATS(jniinvokation();)
3914     *vm = &ptr_jvm;
3915
3916         return 0;
3917 }
3918
3919
3920 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3921 {
3922         STATS(jniinvokation();)
3923         log_text("JNI-Call: GetStringRegion");
3924 }
3925
3926
3927 void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3928 {
3929         STATS(jniinvokation();)
3930         log_text("JNI-Call: GetStringUTFRegion");
3931 }
3932
3933
3934 /* GetPrimitiveArrayCritical ***************************************************
3935
3936    Obtain a direct pointer to array elements.
3937
3938 *******************************************************************************/
3939
3940 void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3941 {
3942         /* do the same as Kaffe does */
3943
3944         return GetByteArrayElements(env, (jbyteArray) array, isCopy);
3945 }
3946
3947
3948 /* ReleasePrimitiveArrayCritical ***********************************************
3949
3950    No specific documentation.
3951
3952 *******************************************************************************/
3953
3954 void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
3955                                                                    jint mode)
3956 {
3957         STATS(jniinvokation();)
3958
3959         /* do the same as Kaffe does */
3960
3961         ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
3962 }
3963
3964
3965 /* GetStringCritical ***********************************************************
3966
3967    The semantics of these two functions are similar to the existing
3968    Get/ReleaseStringChars functions.
3969
3970 *******************************************************************************/
3971
3972 const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
3973 {
3974         STATS(jniinvokation();)
3975
3976         return GetStringChars(env, string, isCopy);
3977 }
3978
3979
3980 void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
3981 {
3982         STATS(jniinvokation();)
3983
3984         ReleaseStringChars(env, string, cstring);
3985 }
3986
3987
3988 jweak NewWeakGlobalRef (JNIEnv* env, jobject obj)
3989 {
3990         STATS(jniinvokation();)
3991         log_text("JNI-Call: NewWeakGlobalRef");
3992
3993         return obj;
3994 }
3995
3996
3997 void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
3998 {
3999         STATS(jniinvokation();)
4000         log_text("JNI-Call: DeleteWeakGlobalRef");
4001
4002         /* empty */
4003 }
4004
4005
4006 /* NewGlobalRef ****************************************************************
4007
4008    Creates a new global reference to the object referred to by the obj
4009    argument.
4010
4011 *******************************************************************************/
4012     
4013 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
4014 {
4015         java_lang_Integer *refcount;
4016         java_objectheader *newval;
4017
4018         STATS(jniinvokation();)
4019
4020 #if defined(USE_THREADS)
4021         builtin_monitorenter(*global_ref_table);
4022 #endif
4023         
4024         refcount = (java_lang_Integer *)
4025                 asm_calljavafunction(getmid, *global_ref_table, lobj, NULL, NULL);
4026
4027         if (refcount == NULL) {
4028                 newval = native_new_and_init_int(class_java_lang_Integer, 1);
4029
4030                 if (newval == NULL) {
4031 #if defined(USE_THREADS)
4032                         builtin_monitorexit(*global_ref_table);
4033 #endif
4034                         return NULL;
4035                 }
4036
4037                 asm_calljavafunction(putmid, *global_ref_table, lobj, newval, NULL);
4038
4039         } else {
4040                 /* we can access the object itself, as we are in a
4041            synchronized section */
4042
4043                 refcount->value++;
4044         }
4045
4046 #if defined(USE_THREADS)
4047         builtin_monitorexit(*global_ref_table);
4048 #endif
4049
4050         return lobj;
4051 }
4052
4053
4054 /* DeleteGlobalRef *************************************************************
4055
4056    Deletes the global reference pointed to by globalRef.
4057
4058 *******************************************************************************/
4059
4060 void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
4061 {
4062         java_lang_Integer *refcount;
4063         s4                 val;
4064
4065         STATS(jniinvokation();)
4066
4067 #if defined(USE_THREADS)
4068         builtin_monitorenter(*global_ref_table);
4069 #endif
4070
4071         refcount = (java_lang_Integer *)
4072                 asm_calljavafunction(getmid, *global_ref_table, globalRef, NULL, NULL);
4073
4074         if (refcount == NULL) {
4075                 log_text("JNI-DeleteGlobalRef: unable to find global reference");
4076                 return;
4077         }
4078
4079         /* we can access the object itself, as we are in a synchronized
4080            section */
4081
4082         val = refcount->value - 1;
4083
4084         if (val == 0) {
4085                 asm_calljavafunction(removemid, *global_ref_table, refcount, NULL,
4086                                                          NULL);
4087
4088         } else {
4089                 /* we do not create a new object, but set the new value into
4090            the old one */
4091
4092                 refcount->value = val;
4093         }
4094
4095 #if defined(USE_THREADS)
4096         builtin_monitorexit(*global_ref_table);
4097 #endif
4098 }
4099
4100
4101 /* ExceptionCheck **************************************************************
4102
4103    Returns JNI_TRUE when there is a pending exception; otherwise,
4104    returns JNI_FALSE.
4105
4106 *******************************************************************************/
4107
4108 jboolean ExceptionCheck(JNIEnv *env)
4109 {
4110         STATS(jniinvokation();)
4111         return *exceptionptr ? JNI_TRUE : JNI_FALSE;
4112 }
4113
4114
4115 /* New JNI 1.4 functions ******************************************************/
4116
4117 /* NewDirectByteBuffer *********************************************************
4118
4119    Allocates and returns a direct java.nio.ByteBuffer referring to the
4120    block of memory starting at the memory address address and
4121    extending capacity bytes.
4122
4123 *******************************************************************************/
4124
4125 jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
4126 {
4127         java_nio_DirectByteBufferImpl *nbuf;
4128 #if SIZEOF_VOID_P == 8
4129         gnu_classpath_Pointer64 *paddress;
4130 #else
4131         gnu_classpath_Pointer32 *paddress;
4132 #endif
4133
4134         STATS(jniinvokation();)
4135
4136         log_text("JNI-NewDirectByteBuffer: called");
4137
4138         /* allocate a java.nio.DirectByteBufferImpl object */
4139
4140         if (!(nbuf = (java_nio_DirectByteBufferImpl *) builtin_new(class_java_nio_DirectByteBufferImpl)))
4141                 return NULL;
4142
4143         /* alocate a gnu.classpath.Pointer{32,64} object */
4144
4145 #if SIZEOF_VOID_P == 8
4146         if (!(paddress = (gnu_classpath_Pointer64 *) builtin_new(class_gnu_classpath_Pointer64)))
4147 #else
4148         if (!(paddress = (gnu_classpath_Pointer32 *) builtin_new(class_gnu_classpath_Pointer32)))
4149 #endif
4150                 return NULL;
4151
4152         /* fill gnu.classpath.Pointer{32,64} with address */
4153
4154         paddress->data = (ptrint) address;
4155
4156         /* fill java.nio.Buffer object */
4157
4158         nbuf->cap     = (s4) capacity;
4159         nbuf->limit   = (s4) capacity;
4160         nbuf->pos     = 0;
4161         nbuf->address = (gnu_classpath_Pointer *) paddress;
4162
4163         /* add local reference and return the value */
4164
4165         return NewLocalRef(env, (jobject) nbuf);
4166 }
4167
4168
4169 /* GetDirectBufferAddress ******************************************************
4170
4171    Fetches and returns the starting address of the memory region
4172    referenced by the given direct java.nio.Buffer.
4173
4174 *******************************************************************************/
4175
4176 void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
4177 {
4178         java_nio_DirectByteBufferImpl *nbuf;
4179 #if SIZEOF_VOID_P == 8
4180         gnu_classpath_Pointer64       *address;
4181 #else
4182         gnu_classpath_Pointer32       *address;
4183 #endif
4184
4185         STATS(jniinvokation();)
4186
4187 #if 0
4188         if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
4189                 return NULL;
4190 #endif
4191
4192         nbuf = (java_nio_DirectByteBufferImpl *) buf;
4193
4194 #if SIZEOF_VOID_P == 8
4195         address = (gnu_classpath_Pointer64 *) nbuf->address;
4196 #else
4197         address = (gnu_classpath_Pointer32 *) nbuf->address;
4198 #endif
4199
4200         return (void *) address->data;
4201 }
4202
4203
4204 /* GetDirectBufferCapacity *****************************************************
4205
4206    Fetches and returns the capacity in bytes of the memory region
4207    referenced by the given direct java.nio.Buffer.
4208
4209 *******************************************************************************/
4210
4211 jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
4212 {
4213         java_nio_Buffer *nbuf;
4214
4215         STATS(jniinvokation();)
4216
4217         if (buf == NULL)
4218                 return -1;
4219
4220         nbuf = (java_nio_Buffer *) buf;
4221
4222         return (jlong) nbuf->cap;
4223 }
4224
4225
4226 jint DestroyJavaVM(JavaVM *vm)
4227 {
4228         STATS(jniinvokation();)
4229         log_text("DestroyJavaVM called");
4230
4231         return 0;
4232 }
4233
4234
4235 /* AttachCurrentThread *********************************************************
4236
4237    Attaches the current thread to a Java VM. Returns a JNI interface
4238    pointer in the JNIEnv argument.
4239
4240    Trying to attach a thread that is already attached is a no-op.
4241
4242    A native thread cannot be attached simultaneously to two Java VMs.
4243
4244    When a thread is attached to the VM, the context class loader is
4245    the bootstrap loader.
4246
4247 *******************************************************************************/
4248
4249 jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
4250 {
4251         STATS(jniinvokation();)
4252
4253         log_text("AttachCurrentThread called");
4254
4255 #if !defined(HAVE___THREAD)
4256 /*      cacao_thread_attach();*/
4257 #else
4258         #error "No idea how to implement that. Perhaps Stefan knows"
4259 #endif
4260
4261         *env = &ptr_env;
4262
4263         return 0;
4264 }
4265
4266
4267 jint DetachCurrentThread(JavaVM *vm)
4268 {
4269         STATS(jniinvokation();)
4270         log_text("DetachCurrentThread called");
4271
4272         return 0;
4273 }
4274
4275
4276 /* GetEnv **********************************************************************
4277
4278    If the current thread is not attached to the VM, sets *env to NULL,
4279    and returns JNI_EDETACHED. If the specified version is not
4280    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
4281    sets *env to the appropriate interface, and returns JNI_OK.
4282
4283 *******************************************************************************/
4284
4285 jint GetEnv(JavaVM *vm, void **env, jint version)
4286 {
4287         STATS(jniinvokation();)
4288
4289 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4290         if (thread_getself() == NULL) {
4291                 *env = NULL;
4292
4293                 return JNI_EDETACHED;
4294         }
4295 #endif
4296
4297         if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
4298                 (version == JNI_VERSION_1_4)) {
4299                 *env = &ptr_env;
4300
4301                 return JNI_OK;
4302         }
4303
4304 #if defined(ENABLE_JVMTI)
4305         if (version == JVMTI_VERSION_1_0) {
4306                 *env = (void *) new_jvmtienv();
4307
4308                 if (env != NULL)
4309                         return JNI_OK;
4310         }
4311 #endif
4312         
4313         *env = NULL;
4314
4315         return JNI_EVERSION;
4316 }
4317
4318
4319
4320 jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
4321 {
4322         STATS(jniinvokation();)
4323         log_text("AttachCurrentThreadAsDaemon called");
4324
4325         return 0;
4326 }
4327
4328
4329 /* JNI invocation table *******************************************************/
4330
4331 const struct JNIInvokeInterface JNI_JavaVMTable = {
4332         NULL,
4333         NULL,
4334         NULL,
4335
4336         DestroyJavaVM,
4337         AttachCurrentThread,
4338         DetachCurrentThread,
4339         GetEnv,
4340         AttachCurrentThreadAsDaemon
4341 };
4342
4343
4344 /* JNI function table *********************************************************/
4345
4346 struct JNINativeInterface JNI_JNIEnvTable = {
4347         NULL,
4348         NULL,
4349         NULL,
4350         NULL,    
4351         &GetVersion,
4352
4353         &DefineClass,
4354         &FindClass,
4355         &FromReflectedMethod,
4356         &FromReflectedField,
4357         &ToReflectedMethod,
4358         &GetSuperclass,
4359         &IsAssignableFrom,
4360         &ToReflectedField,
4361
4362         &Throw,
4363         &ThrowNew,
4364         &ExceptionOccurred,
4365         &ExceptionDescribe,
4366         &ExceptionClear,
4367         &FatalError,
4368         &PushLocalFrame,
4369         &PopLocalFrame,
4370
4371         &NewGlobalRef,
4372         &DeleteGlobalRef,
4373         &DeleteLocalRef,
4374         &IsSameObject,
4375         &NewLocalRef,
4376         &EnsureLocalCapacity,
4377
4378         &AllocObject,
4379         &NewObject,
4380         &NewObjectV,
4381         &NewObjectA,
4382
4383         &GetObjectClass,
4384         &IsInstanceOf,
4385
4386         &GetMethodID,
4387
4388         &CallObjectMethod,
4389         &CallObjectMethodV,
4390         &CallObjectMethodA,
4391         &CallBooleanMethod,
4392         &CallBooleanMethodV,
4393         &CallBooleanMethodA,
4394         &CallByteMethod,
4395         &CallByteMethodV,
4396         &CallByteMethodA,
4397         &CallCharMethod,
4398         &CallCharMethodV,
4399         &CallCharMethodA,
4400         &CallShortMethod,
4401         &CallShortMethodV,
4402         &CallShortMethodA,
4403         &CallIntMethod,
4404         &CallIntMethodV,
4405         &CallIntMethodA,
4406         &CallLongMethod,
4407         &CallLongMethodV,
4408         &CallLongMethodA,
4409         &CallFloatMethod,
4410         &CallFloatMethodV,
4411         &CallFloatMethodA,
4412         &CallDoubleMethod,
4413         &CallDoubleMethodV,
4414         &CallDoubleMethodA,
4415         &CallVoidMethod,
4416         &CallVoidMethodV,
4417         &CallVoidMethodA,
4418
4419         &CallNonvirtualObjectMethod,
4420         &CallNonvirtualObjectMethodV,
4421         &CallNonvirtualObjectMethodA,
4422         &CallNonvirtualBooleanMethod,
4423         &CallNonvirtualBooleanMethodV,
4424         &CallNonvirtualBooleanMethodA,
4425         &CallNonvirtualByteMethod,
4426         &CallNonvirtualByteMethodV,
4427         &CallNonvirtualByteMethodA,
4428         &CallNonvirtualCharMethod,
4429         &CallNonvirtualCharMethodV,
4430         &CallNonvirtualCharMethodA,
4431         &CallNonvirtualShortMethod,
4432         &CallNonvirtualShortMethodV,
4433         &CallNonvirtualShortMethodA,
4434         &CallNonvirtualIntMethod,
4435         &CallNonvirtualIntMethodV,
4436         &CallNonvirtualIntMethodA,
4437         &CallNonvirtualLongMethod,
4438         &CallNonvirtualLongMethodV,
4439         &CallNonvirtualLongMethodA,
4440         &CallNonvirtualFloatMethod,
4441         &CallNonvirtualFloatMethodV,
4442         &CallNonvirtualFloatMethodA,
4443         &CallNonvirtualDoubleMethod,
4444         &CallNonvirtualDoubleMethodV,
4445         &CallNonvirtualDoubleMethodA,
4446         &CallNonvirtualVoidMethod,
4447         &CallNonvirtualVoidMethodV,
4448         &CallNonvirtualVoidMethodA,
4449
4450         &GetFieldID,
4451
4452         &GetObjectField,
4453         &GetBooleanField,
4454         &GetByteField,
4455         &GetCharField,
4456         &GetShortField,
4457         &GetIntField,
4458         &GetLongField,
4459         &GetFloatField,
4460         &GetDoubleField,
4461         &SetObjectField,
4462         &SetBooleanField,
4463         &SetByteField,
4464         &SetCharField,
4465         &SetShortField,
4466         &SetIntField,
4467         &SetLongField,
4468         &SetFloatField,
4469         &SetDoubleField,
4470
4471         &GetStaticMethodID,
4472
4473         &CallStaticObjectMethod,
4474         &CallStaticObjectMethodV,
4475         &CallStaticObjectMethodA,
4476         &CallStaticBooleanMethod,
4477         &CallStaticBooleanMethodV,
4478         &CallStaticBooleanMethodA,
4479         &CallStaticByteMethod,
4480         &CallStaticByteMethodV,
4481         &CallStaticByteMethodA,
4482         &CallStaticCharMethod,
4483         &CallStaticCharMethodV,
4484         &CallStaticCharMethodA,
4485         &CallStaticShortMethod,
4486         &CallStaticShortMethodV,
4487         &CallStaticShortMethodA,
4488         &CallStaticIntMethod,
4489         &CallStaticIntMethodV,
4490         &CallStaticIntMethodA,
4491         &CallStaticLongMethod,
4492         &CallStaticLongMethodV,
4493         &CallStaticLongMethodA,
4494         &CallStaticFloatMethod,
4495         &CallStaticFloatMethodV,
4496         &CallStaticFloatMethodA,
4497         &CallStaticDoubleMethod,
4498         &CallStaticDoubleMethodV,
4499         &CallStaticDoubleMethodA,
4500         &CallStaticVoidMethod,
4501         &CallStaticVoidMethodV,
4502         &CallStaticVoidMethodA,
4503
4504         &GetStaticFieldID,
4505
4506         &GetStaticObjectField,
4507         &GetStaticBooleanField,
4508         &GetStaticByteField,
4509         &GetStaticCharField,
4510         &GetStaticShortField,
4511         &GetStaticIntField,
4512         &GetStaticLongField,
4513         &GetStaticFloatField,
4514         &GetStaticDoubleField,
4515         &SetStaticObjectField,
4516         &SetStaticBooleanField,
4517         &SetStaticByteField,
4518         &SetStaticCharField,
4519         &SetStaticShortField,
4520         &SetStaticIntField,
4521         &SetStaticLongField,
4522         &SetStaticFloatField,
4523         &SetStaticDoubleField,
4524
4525         &NewString,
4526         &GetStringLength,
4527         &GetStringChars,
4528         &ReleaseStringChars,
4529
4530         &NewStringUTF,
4531         &GetStringUTFLength,
4532         &GetStringUTFChars,
4533         &ReleaseStringUTFChars,
4534
4535         &GetArrayLength,
4536
4537         &NewObjectArray,
4538         &GetObjectArrayElement,
4539         &SetObjectArrayElement,
4540
4541         &NewBooleanArray,
4542         &NewByteArray,
4543         &NewCharArray,
4544         &NewShortArray,
4545         &NewIntArray,
4546         &NewLongArray,
4547         &NewFloatArray,
4548         &NewDoubleArray,
4549
4550         &GetBooleanArrayElements,
4551         &GetByteArrayElements,
4552         &GetCharArrayElements,
4553         &GetShortArrayElements,
4554         &GetIntArrayElements,
4555         &GetLongArrayElements,
4556         &GetFloatArrayElements,
4557         &GetDoubleArrayElements,
4558
4559         &ReleaseBooleanArrayElements,
4560         &ReleaseByteArrayElements,
4561         &ReleaseCharArrayElements,
4562         &ReleaseShortArrayElements,
4563         &ReleaseIntArrayElements,
4564         &ReleaseLongArrayElements,
4565         &ReleaseFloatArrayElements,
4566         &ReleaseDoubleArrayElements,
4567
4568         &GetBooleanArrayRegion,
4569         &GetByteArrayRegion,
4570         &GetCharArrayRegion,
4571         &GetShortArrayRegion,
4572         &GetIntArrayRegion,
4573         &GetLongArrayRegion,
4574         &GetFloatArrayRegion,
4575         &GetDoubleArrayRegion,
4576         &SetBooleanArrayRegion,
4577         &SetByteArrayRegion,
4578         &SetCharArrayRegion,
4579         &SetShortArrayRegion,
4580         &SetIntArrayRegion,
4581         &SetLongArrayRegion,
4582         &SetFloatArrayRegion,
4583         &SetDoubleArrayRegion,
4584
4585         &RegisterNatives,
4586         &UnregisterNatives,
4587
4588         &MonitorEnter,
4589         &MonitorExit,
4590
4591         &GetJavaVM,
4592
4593         /* new JNI 1.2 functions */
4594
4595         &GetStringRegion,
4596         &GetStringUTFRegion,
4597
4598         &GetPrimitiveArrayCritical,
4599         &ReleasePrimitiveArrayCritical,
4600
4601         &GetStringCritical,
4602         &ReleaseStringCritical,
4603
4604         &NewWeakGlobalRef,
4605         &DeleteWeakGlobalRef,
4606
4607         &ExceptionCheck,
4608
4609         /* new JNI 1.4 functions */
4610
4611         &NewDirectByteBuffer,
4612         &GetDirectBufferAddress,
4613         &GetDirectBufferCapacity
4614 };
4615
4616
4617 /* Invocation API Functions ***************************************************/
4618
4619 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4620
4621    Returns a default configuration for the Java VM.
4622
4623 *******************************************************************************/
4624
4625 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4626 {
4627         JDK1_1InitArgs *_vm_args = (JDK1_1InitArgs *) vm_args;
4628
4629         /* GNU classpath currently supports JNI 1.2 */
4630
4631         _vm_args->version = JNI_VERSION_1_2;
4632
4633         return 0;
4634 }
4635
4636
4637 /* JNI_GetCreatedJavaVMs *******************************************************
4638
4639    Returns all Java VMs that have been created. Pointers to VMs are written in
4640    the buffer vmBuf in the order they are created. At most bufLen number of
4641    entries will be written. The total number of created VMs is returned in
4642    *nVMs.
4643
4644 *******************************************************************************/
4645
4646 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4647 {
4648         log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
4649
4650         return 0;
4651 }
4652
4653
4654 /* JNI_CreateJavaVM ************************************************************
4655
4656    Loads and initializes a Java VM. The current thread becomes the main thread.
4657    Sets the env argument to the JNI interface pointer of the main thread.
4658
4659 *******************************************************************************/
4660
4661 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args)
4662 {
4663         const struct JNIInvokeInterface *vm;
4664         struct JNINativeInterface *env;
4665
4666         vm = &JNI_JavaVMTable;
4667         env = &JNI_JNIEnvTable;
4668
4669         *p_vm = (JavaVM *) vm;
4670         *p_env = (JNIEnv *) env;
4671
4672         return 0;
4673 }
4674
4675
4676 jobject *jni_method_invokeNativeHelper(JNIEnv *env, methodinfo *methodID,
4677                                                                            jobject obj, java_objectarray *params)
4678 {
4679         jni_callblock *blk;
4680         jobject        o;
4681         s4             argcount;
4682         s4             paramcount;
4683
4684         if (methodID == 0) {
4685                 *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
4686                 return NULL;
4687         }
4688
4689         argcount = methodID->parseddesc->paramcount;
4690         paramcount = argcount;
4691
4692         /* if method is non-static, remove the `this' pointer */
4693
4694         if (!(methodID->flags & ACC_STATIC))
4695                 paramcount--;
4696
4697         /* the method is an instance method the obj has to be an instance of the 
4698            class the method belongs to. For static methods the obj parameter
4699            is ignored. */
4700
4701         if (!(methodID->flags & ACC_STATIC) && obj &&
4702                 (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
4703                 *exceptionptr =
4704                         new_exception_message(string_java_lang_IllegalArgumentException,
4705                                                                                           "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
4706                 return NULL;
4707         }
4708
4709         if (((params == NULL) && (paramcount != 0)) ||
4710                 (params && (params->header.size != paramcount))) {
4711                 *exceptionptr =
4712                         new_exception(string_java_lang_IllegalArgumentException);
4713                 return NULL;
4714         }
4715
4716
4717         if (!(methodID->flags & ACC_STATIC) && !obj)  {
4718                 *exceptionptr =
4719                         new_exception_message(string_java_lang_NullPointerException,
4720                                                                   "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
4721                 return NULL;
4722         }
4723
4724         if ((methodID->flags & ACC_STATIC) && (obj))
4725                 obj = NULL;
4726
4727         if (obj) {
4728                 if ((methodID->flags & ACC_ABSTRACT) ||
4729                         (methodID->class->flags & ACC_INTERFACE)) {
4730                         methodID = get_virtual(obj, methodID);
4731                 }
4732         }
4733
4734         blk = MNEW(jni_callblock, argcount);
4735
4736         if (!fill_callblock_from_objectarray(obj, methodID->parseddesc, blk,
4737                                                                                  params))
4738                 return NULL;
4739
4740         switch (methodID->parseddesc->returntype.decltype) {
4741         case TYPE_VOID:
4742                 (void) asm_calljavafunction2(methodID, argcount,
4743                                                                          argcount * sizeof(jni_callblock),
4744                                                                          blk);
4745                 o = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
4746                 break;
4747
4748         case PRIMITIVETYPE_INT: {
4749                 s4 i;
4750                 i = asm_calljavafunction2int(methodID, argcount,
4751                                                                          argcount * sizeof(jni_callblock),
4752                                                                          blk);
4753
4754                 o = native_new_and_init_int(class_java_lang_Integer, i);
4755         }
4756         break;
4757
4758         case PRIMITIVETYPE_BYTE: {
4759                 s4 i;
4760                 i = asm_calljavafunction2int(methodID, argcount,
4761                                                                          argcount * sizeof(jni_callblock),
4762                                                                          blk);
4763
4764 /*              o = native_new_and_init_int(class_java_lang_Byte, i); */
4765                 o = builtin_new(class_java_lang_Byte);
4766                 CallVoidMethod(env,
4767                                            o,
4768                                            class_resolvemethod(o->vftbl->class,
4769                                                                                    utf_init,
4770                                                                                    utf_byte__void),
4771                                            i);
4772         }
4773         break;
4774
4775         case PRIMITIVETYPE_CHAR: {
4776                 s4 intVal;
4777                 intVal = asm_calljavafunction2int(methodID,
4778                                                                                   argcount,
4779                                                                                   argcount * sizeof(jni_callblock),
4780                                                                                   blk);
4781                 o = builtin_new(class_java_lang_Character);
4782                 CallVoidMethod(env,
4783                                            o,
4784                                            class_resolvemethod(o->vftbl->class,
4785                                                                                    utf_init,
4786                                                                                    utf_char__void),
4787                                            intVal);
4788         }
4789         break;
4790
4791         case PRIMITIVETYPE_SHORT: {
4792                 s4 intVal;
4793                 intVal = asm_calljavafunction2int(methodID,
4794                                                                                   argcount,
4795                                                                                   argcount * sizeof(jni_callblock),
4796                                                                                   blk);
4797                 o = builtin_new(class_java_lang_Short);
4798                 CallVoidMethod(env,
4799                                            o,
4800                                            class_resolvemethod(o->vftbl->class,
4801                                                                                    utf_init,
4802                                                                                    utf_short__void),
4803                                            intVal);
4804         }
4805         break;
4806
4807         case PRIMITIVETYPE_BOOLEAN: {
4808                 s4 intVal;
4809                 intVal = asm_calljavafunction2int(methodID,
4810                                                                                   argcount,
4811                                                                                   argcount * sizeof(jni_callblock),
4812                                                                                   blk);
4813                 o = builtin_new(class_java_lang_Boolean);
4814                 CallVoidMethod(env,
4815                                            o,
4816                                            class_resolvemethod(o->vftbl->class,
4817                                                                                    utf_init,
4818                                                                                    utf_boolean__void),
4819                                            intVal);
4820         }
4821         break;
4822
4823         case PRIMITIVETYPE_LONG: {
4824                 jlong longVal;
4825                 longVal = asm_calljavafunction2long(methodID,
4826                                                                                         argcount,
4827                                                                                         argcount * sizeof(jni_callblock),
4828                                                                                         blk);
4829                 o = builtin_new(class_java_lang_Long);
4830                 CallVoidMethod(env,
4831                                            o,
4832                                            class_resolvemethod(o->vftbl->class,
4833                                                                                    utf_init,
4834                                                                                    utf_long__void),
4835                                            longVal);
4836         }
4837         break;
4838
4839         case PRIMITIVETYPE_FLOAT: {
4840                 jdouble floatVal;       
4841                 floatVal = asm_calljavafunction2float(methodID,
4842                                                                                           argcount,
4843                                                                                           argcount * sizeof(jni_callblock),
4844                                                                                           blk);
4845                 o = builtin_new(class_java_lang_Float);
4846                 CallVoidMethod(env,
4847                                            o,
4848                                            class_resolvemethod(o->vftbl->class,
4849                                                                                    utf_init,
4850                                                                                    utf_float__void),
4851                                            floatVal);
4852         }
4853         break;
4854
4855         case PRIMITIVETYPE_DOUBLE: {
4856                 jdouble doubleVal;
4857                 doubleVal = asm_calljavafunction2double(methodID,
4858                                                                                                 argcount,
4859                                                                                                 argcount * sizeof(jni_callblock),
4860                                                                                                 blk);
4861                 o = builtin_new(class_java_lang_Double);
4862                 CallVoidMethod(env,
4863                                            o,
4864                                            class_resolvemethod(o->vftbl->class,
4865                                                                                    utf_init,
4866                                                                                    utf_double__void),
4867                                            doubleVal);
4868         }
4869         break;
4870
4871         case TYPE_ADR:
4872                 o = asm_calljavafunction2(methodID, argcount,
4873                                                                   argcount * sizeof(jni_callblock), blk);
4874                 break;
4875
4876         default:
4877                 /* if this happens the exception has already been set by              */
4878                 /* fill_callblock_from_objectarray                                    */
4879
4880                 MFREE(blk, jni_callblock, argcount);
4881                 return (jobject *) 0;
4882         }
4883
4884         MFREE(blk, jni_callblock, argcount);
4885
4886         if (*exceptionptr) {
4887                 java_objectheader *cause;
4888
4889                 cause = *exceptionptr;
4890
4891                 /* clear exception pointer, we are calling JIT code again */
4892
4893                 *exceptionptr = NULL;
4894
4895                 *exceptionptr =
4896                         new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
4897                                                                         (java_lang_Throwable *) cause);
4898         }
4899
4900         return (jobject *) o;
4901 }
4902
4903
4904 /*
4905  * These are local overrides for various environment variables in Emacs.
4906  * Please do not remove this and leave it at the end of the file, where
4907  * Emacs will automagically detect them.
4908  * ---------------------------------------------------------------------
4909  * Local variables:
4910  * mode: c
4911  * indent-tabs-mode: t
4912  * c-basic-offset: 4
4913  * tab-width: 4
4914  * End:
4915  */