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