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