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