* src/native/vm/java_lang_reflect_Constructor.c: Removed.
[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, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <string.h>
31
32 #include "vm/types.h"
33
34 #include "mm/gc-common.h"
35 #include "mm/memory.h"
36
37 #include "native/jni.h"
38 #include "native/llni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
41
42 #if defined(ENABLE_JAVASE)
43 # if defined(WITH_CLASSPATH_GNU)
44 #  include "native/include/gnu_classpath_Pointer.h"
45
46 #  if SIZEOF_VOID_P == 8
47 #   include "native/include/gnu_classpath_Pointer64.h"
48 #  else
49 #   include "native/include/gnu_classpath_Pointer32.h"
50 #  endif
51 # endif
52 #endif
53
54 #include "native/include/java_lang_Object.h"
55 #include "native/include/java_lang_String.h"
56 #include "native/include/java_lang_Throwable.h"
57
58 #if defined(ENABLE_JAVASE)
59 # if defined(WITH_CLASSPATH_SUN)
60 #  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
61 # endif
62
63 /* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
64    we pre-define it here to prevent a compiler warning for Sun
65    configurations. */
66
67 struct java_lang_ClassLoader;
68
69 # include "native/include/java_lang_Class.h"
70 # include "native/include/java_lang_ClassLoader.h"
71
72 # include "native/include/java_lang_reflect_Constructor.h"
73 # include "native/include/java_lang_reflect_Field.h"
74 # include "native/include/java_lang_reflect_Method.h"
75
76 # include "native/include/java_nio_Buffer.h"
77
78 # if defined(WITH_CLASSPATH_GNU)
79 #  include "native/include/java_nio_DirectByteBufferImpl.h"
80 # endif
81 #endif
82
83 #if defined(ENABLE_JVMTI)
84 # include "native/jvmti/cacaodbg.h"
85 #endif
86
87 #include "native/vm/java_lang_Class.h"
88
89 #if defined(ENABLE_JAVASE)
90 # include "native/vm/reflect.h"
91 #endif
92
93 #include "threads/lock-common.h"
94 #include "threads/thread.h"
95
96 #include "toolbox/logging.h"
97
98 #include "vm/array.h"
99 #include "vm/builtin.h"
100 #include "vm/exceptions.h"
101 #include "vm/global.h"
102 #include "vm/initialize.h"
103 #include "vm/primitive.h"
104 #include "vm/resolve.h"
105 #include "vm/stringlocal.h"
106 #include "vm/vm.h"
107
108 #include "vm/jit/argument.h"
109 #include "vm/jit/asmpart.h"
110 #include "vm/jit/jit.h"
111 #include "vm/jit/stacktrace.h"
112
113 #include "vmcore/loader.h"
114 #include "vmcore/options.h"
115 #include "vmcore/statistics.h"
116
117
118 /* debug **********************************************************************/
119
120 #if !defined(NDEBUG)
121 # define TRACEJNICALLS(text)                                    \
122     do {                                                                                \
123         if (opt_TraceJNICalls) {                                \
124             log_println text;                                   \
125         }                                                                               \
126     } while (0)
127 #else
128 # define TRACEJNICALLS(text)
129 #endif
130
131
132 /* global variables ***********************************************************/
133
134 /* global reference table *****************************************************/
135
136 /* hashsize must be power of 2 */
137
138 #define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
139
140 static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
141
142
143 /* direct buffer stuff ********************************************************/
144
145 #if defined(ENABLE_JAVASE)
146 static classinfo *class_java_nio_Buffer;
147
148 # if defined(WITH_CLASSPATH_GNU)
149
150 static classinfo *class_java_nio_DirectByteBufferImpl;
151 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
152
153 #  if SIZEOF_VOID_P == 8
154 static classinfo *class_gnu_classpath_Pointer64;
155 #  else
156 static classinfo *class_gnu_classpath_Pointer32;
157 #  endif
158
159 static methodinfo *dbbirw_init;
160
161 # elif defined(WITH_CLASSPATH_SUN)
162
163 static classinfo *class_sun_nio_ch_DirectBuffer;
164 static classinfo *class_java_nio_DirectByteBuffer;
165
166 static methodinfo *dbb_init;
167
168 # endif
169 #endif
170
171
172 /* some forward declarations **************************************************/
173
174 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
175
176
177 /* jni_init ********************************************************************
178
179    Initialize the JNI subsystem.
180
181 *******************************************************************************/
182
183 bool jni_init(void)
184 {
185         TRACESUBSYSTEMINITIALIZATION("jni_init");
186
187         /* create global ref hashtable */
188
189         hashtable_global_ref = NEW(hashtable);
190
191         hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
192
193
194 #if defined(ENABLE_JAVASE)
195         /* Direct buffer stuff. */
196
197         if (!(class_java_nio_Buffer =
198                   load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
199                 !link_class(class_java_nio_Buffer))
200                 return false;
201
202 # if defined(WITH_CLASSPATH_GNU)
203
204         if (!(class_java_nio_DirectByteBufferImpl =
205                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
206                 !link_class(class_java_nio_DirectByteBufferImpl))
207                 return false;
208
209         if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
210                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
211                 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
212                 return false;
213
214         if (!(dbbirw_init =
215                 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
216                                                         utf_init,
217                                                         utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
218                 return false;
219
220 #  if SIZEOF_VOID_P == 8
221         if (!(class_gnu_classpath_Pointer64 =
222                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
223                 !link_class(class_gnu_classpath_Pointer64))
224                 return false;
225 #  else
226         if (!(class_gnu_classpath_Pointer32 =
227                   load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
228                 !link_class(class_gnu_classpath_Pointer32))
229                 return false;
230 #  endif
231
232 # elif defined(WITH_CLASSPATH_SUN)
233
234         if (!(class_sun_nio_ch_DirectBuffer =
235                   load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
236                 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
237
238         if (!link_class(class_sun_nio_ch_DirectBuffer))
239                 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
240
241         if (!(class_java_nio_DirectByteBuffer =
242                   load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
243                 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
244
245         if (!link_class(class_java_nio_DirectByteBuffer))
246                 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
247
248         if (!(dbb_init =
249                   class_resolvemethod(class_java_nio_DirectByteBuffer,
250                                                           utf_init,
251                                                           utf_new_char("(JI)V"))))
252                 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
253
254 # endif
255
256 #endif /* defined(ENABLE_JAVASE) */
257
258         return true;
259 }
260
261
262 /* jni_version_check ***********************************************************
263
264    Check if the given JNI version is supported.
265
266    IN:
267        version....JNI version to check
268
269    RETURN VALUE:
270        true.......supported
271        false......not supported
272
273 *******************************************************************************/
274
275 bool jni_version_check(int version)
276 {
277         switch (version) {
278         case JNI_VERSION_1_1:
279         case JNI_VERSION_1_2:
280         case JNI_VERSION_1_4:
281         case JNI_VERSION_1_6:
282                 return true;
283         default:
284                 return false;
285         }
286 }
287
288
289 /* _Jv_jni_CallObjectMethod ****************************************************
290
291    Internal function to call Java Object methods.
292
293 *******************************************************************************/
294
295 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
296                                                                                            vftbl_t *vftbl,
297                                                                                            methodinfo *m, va_list ap)
298 {
299         methodinfo    *resm;
300         java_handle_t *ro;
301
302         STATISTICS(jniinvokation());
303
304         if (m == NULL) {
305                 exceptions_throw_nullpointerexception();
306                 return NULL;
307         }
308
309         /* Class initialization is done by the JIT compiler.  This is ok
310            since a static method always belongs to the declaring class. */
311
312         if (m->flags & ACC_STATIC) {
313                 /* For static methods we reset the object. */
314
315                 if (o != NULL)
316                         o = NULL;
317
318                 /* for convenience */
319
320                 resm = m;
321
322         } else {
323                 /* For instance methods we make a virtual function table lookup. */
324
325                 resm = method_vftbl_lookup(vftbl, m);
326         }
327
328         STATISTICS(jnicallXmethodnvokation());
329
330         ro = vm_call_method_valist(resm, o, ap);
331
332         return ro;
333 }
334
335
336 /* _Jv_jni_CallObjectMethodA ***************************************************
337
338    Internal function to call Java Object methods.
339
340 *******************************************************************************/
341
342 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
343                                                                                                 vftbl_t *vftbl,
344                                                                                                 methodinfo *m,
345                                                                                                 const jvalue *args)
346 {
347         methodinfo    *resm;
348         java_handle_t *ro;
349
350         STATISTICS(jniinvokation());
351
352         if (m == NULL) {
353                 exceptions_throw_nullpointerexception();
354                 return NULL;
355         }
356
357         /* Class initialization is done by the JIT compiler.  This is ok
358            since a static method always belongs to the declaring class. */
359
360         if (m->flags & ACC_STATIC) {
361                 /* For static methods we reset the object. */
362
363                 if (o != NULL)
364                         o = NULL;
365
366                 /* for convenience */
367
368                 resm = m;
369
370         } else {
371                 /* For instance methods we make a virtual function table lookup. */
372
373                 resm = method_vftbl_lookup(vftbl, m);
374         }
375
376         STATISTICS(jnicallXmethodnvokation());
377
378         ro = vm_call_method_jvalue(resm, o, args);
379
380         return ro;
381 }
382
383
384 /* _Jv_jni_CallIntMethod *******************************************************
385
386    Internal function to call Java integer class methods (boolean,
387    byte, char, short, int).
388
389 *******************************************************************************/
390
391 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
392                                                                   methodinfo *m, va_list ap)
393 {
394         methodinfo *resm;
395         jint        i;
396
397         STATISTICS(jniinvokation());
398
399         if (m == NULL) {
400                 exceptions_throw_nullpointerexception();
401                 return 0;
402         }
403         
404         /* Class initialization is done by the JIT compiler.  This is ok
405            since a static method always belongs to the declaring class. */
406
407         if (m->flags & ACC_STATIC) {
408                 /* For static methods we reset the object. */
409
410                 if (o != NULL)
411                         o = NULL;
412
413                 /* for convenience */
414
415                 resm = m;
416
417         } else {
418                 /* For instance methods we make a virtual function table lookup. */
419
420                 resm = method_vftbl_lookup(vftbl, m);
421         }
422
423         STATISTICS(jnicallXmethodnvokation());
424
425         i = vm_call_method_int_valist(resm, o, ap);
426
427         return i;
428 }
429
430
431 /* _Jv_jni_CallIntMethodA ******************************************************
432
433    Internal function to call Java integer class methods (boolean,
434    byte, char, short, int).
435
436 *******************************************************************************/
437
438 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
439                                                                    methodinfo *m, const jvalue *args)
440 {
441         methodinfo *resm;
442         jint        i;
443
444         STATISTICS(jniinvokation());
445
446         if (m == NULL) {
447                 exceptions_throw_nullpointerexception();
448                 return 0;
449         }
450         
451         /* Class initialization is done by the JIT compiler.  This is ok
452            since a static method always belongs to the declaring class. */
453
454         if (m->flags & ACC_STATIC) {
455                 /* For static methods we reset the object. */
456
457                 if (o != NULL)
458                         o = NULL;
459
460                 /* for convenience */
461
462                 resm = m;
463
464         } else {
465                 /* For instance methods we make a virtual function table lookup. */
466
467                 resm = method_vftbl_lookup(vftbl, m);
468         }
469
470         STATISTICS(jnicallXmethodnvokation());
471
472         i = vm_call_method_int_jvalue(resm, o, args);
473
474         return i;
475 }
476
477
478 /* _Jv_jni_CallLongMethod ******************************************************
479
480    Internal function to call Java long methods.
481
482 *******************************************************************************/
483
484 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
485                                                                         methodinfo *m, va_list ap)
486 {
487         methodinfo *resm;
488         jlong       l;
489
490         STATISTICS(jniinvokation());
491
492         if (m == NULL) {
493                 exceptions_throw_nullpointerexception();
494                 return 0;
495         }
496
497         /* Class initialization is done by the JIT compiler.  This is ok
498            since a static method always belongs to the declaring class. */
499
500         if (m->flags & ACC_STATIC) {
501                 /* For static methods we reset the object. */
502
503                 if (o != NULL)
504                         o = NULL;
505
506                 /* for convenience */
507
508                 resm = m;
509
510         } else {
511                 /* For instance methods we make a virtual function table lookup. */
512
513                 resm = method_vftbl_lookup(vftbl, m);
514         }
515
516         STATISTICS(jnicallXmethodnvokation());
517
518         l = vm_call_method_long_valist(resm, o, ap);
519
520         return l;
521 }
522
523
524 /* _Jv_jni_CallLongMethodA *****************************************************
525
526    Internal function to call Java long methods.
527
528 *******************************************************************************/
529
530 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
531                                                                          methodinfo *m, const jvalue *args)
532 {
533         methodinfo *resm;
534         jlong       l;
535
536         STATISTICS(jniinvokation());
537
538         if (m == NULL) {
539                 exceptions_throw_nullpointerexception();
540                 return 0;
541         }
542
543         /* Class initialization is done by the JIT compiler.  This is ok
544            since a static method always belongs to the declaring class. */
545
546         if (m->flags & ACC_STATIC) {
547                 /* For static methods we reset the object. */
548
549                 if (o != NULL)
550                         o = NULL;
551
552                 /* for convenience */
553
554                 resm = m;
555         }
556         else {
557                 /* For instance methods we make a virtual function table lookup. */
558
559                 resm = method_vftbl_lookup(vftbl, m);
560         }
561
562         STATISTICS(jnicallXmethodnvokation());
563
564         l = vm_call_method_long_jvalue(resm, o, args);
565
566         return l;
567 }
568
569
570 /* _Jv_jni_CallFloatMethod *****************************************************
571
572    Internal function to call Java float methods.
573
574 *******************************************************************************/
575
576 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
577                                                                           methodinfo *m, va_list ap)
578 {
579         methodinfo *resm;
580         jfloat      f;
581
582         /* Class initialization is done by the JIT compiler.  This is ok
583            since a static method always belongs to the declaring class. */
584
585         if (m->flags & ACC_STATIC) {
586                 /* For static methods we reset the object. */
587
588                 if (o != NULL)
589                         o = NULL;
590
591                 /* for convenience */
592
593                 resm = m;
594
595         } else {
596                 /* For instance methods we make a virtual function table lookup. */
597
598                 resm = method_vftbl_lookup(vftbl, m);
599         }
600
601         STATISTICS(jnicallXmethodnvokation());
602
603         f = vm_call_method_float_valist(resm, o, ap);
604
605         return f;
606 }
607
608
609 /* _Jv_jni_CallFloatMethodA ****************************************************
610
611    Internal function to call Java float methods.
612
613 *******************************************************************************/
614
615 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
616                                                                            methodinfo *m, const jvalue *args)
617 {
618         methodinfo *resm;
619         jfloat      f;
620
621         /* Class initialization is done by the JIT compiler.  This is ok
622            since a static method always belongs to the declaring class. */
623
624         if (m->flags & ACC_STATIC) {
625                 /* For static methods we reset the object. */
626
627                 if (o != NULL)
628                         o = NULL;
629
630                 /* for convenience */
631
632                 resm = m;
633         }
634         else {
635                 /* For instance methods we make a virtual function table lookup. */
636
637                 resm = method_vftbl_lookup(vftbl, m);
638         }
639
640         STATISTICS(jnicallXmethodnvokation());
641
642         f = vm_call_method_float_jvalue(resm, o, args);
643
644         return f;
645 }
646
647
648 /* _Jv_jni_CallDoubleMethod ****************************************************
649
650    Internal function to call Java double methods.
651
652 *******************************************************************************/
653
654 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
655                                                                                 methodinfo *m, va_list ap)
656 {
657         methodinfo *resm;
658         jdouble     d;
659
660         /* Class initialization is done by the JIT compiler.  This is ok
661            since a static method always belongs to the declaring class. */
662
663         if (m->flags & ACC_STATIC) {
664                 /* For static methods we reset the object. */
665
666                 if (o != NULL)
667                         o = NULL;
668
669                 /* for convenience */
670
671                 resm = m;
672
673         } else {
674                 /* For instance methods we make a virtual function table lookup. */
675
676                 resm = method_vftbl_lookup(vftbl, m);
677         }
678
679         d = vm_call_method_double_valist(resm, o, ap);
680
681         return d;
682 }
683
684
685 /* _Jv_jni_CallDoubleMethodA ***************************************************
686
687    Internal function to call Java double methods.
688
689 *******************************************************************************/
690
691 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
692                                                                                  methodinfo *m, const jvalue *args)
693 {
694         methodinfo *resm;
695         jdouble     d;
696
697         /* Class initialization is done by the JIT compiler.  This is ok
698            since a static method always belongs to the declaring class. */
699
700         if (m->flags & ACC_STATIC) {
701                 /* For static methods we reset the object. */
702
703                 if (o != NULL)
704                         o = NULL;
705
706                 /* for convenience */
707
708                 resm = m;
709         }
710         else {
711                 /* For instance methods we make a virtual function table lookup. */
712
713                 resm = method_vftbl_lookup(vftbl, m);
714         }
715
716         d = vm_call_method_double_jvalue(resm, o, args);
717
718         return d;
719 }
720
721
722 /* _Jv_jni_CallVoidMethod ******************************************************
723
724    Internal function to call Java void methods.
725
726 *******************************************************************************/
727
728 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
729                                                                    methodinfo *m, va_list ap)
730 {       
731         methodinfo *resm;
732
733         if (m == NULL) {
734                 exceptions_throw_nullpointerexception();
735                 return;
736         }
737
738         /* Class initialization is done by the JIT compiler.  This is ok
739            since a static method always belongs to the declaring class. */
740
741         if (m->flags & ACC_STATIC) {
742                 /* For static methods we reset the object. */
743
744                 if (o != NULL)
745                         o = NULL;
746
747                 /* for convenience */
748
749                 resm = m;
750
751         } else {
752                 /* For instance methods we make a virtual function table lookup. */
753
754                 resm = method_vftbl_lookup(vftbl, m);
755         }
756
757         STATISTICS(jnicallXmethodnvokation());
758
759         (void) vm_call_method_valist(resm, o, ap);
760 }
761
762
763 /* _Jv_jni_CallVoidMethodA *****************************************************
764
765    Internal function to call Java void methods.
766
767 *******************************************************************************/
768
769 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
770                                                                         methodinfo *m, const jvalue *args)
771 {       
772         methodinfo *resm;
773
774         if (m == NULL) {
775                 exceptions_throw_nullpointerexception();
776                 return;
777         }
778
779         /* Class initialization is done by the JIT compiler.  This is ok
780            since a static method always belongs to the declaring class. */
781
782         if (m->flags & ACC_STATIC) {
783                 /* For static methods we reset the object. */
784
785                 if (o != NULL)
786                         o = NULL;
787
788                 /* for convenience */
789
790                 resm = m;
791
792         } else {
793                 /* For instance methods we make a virtual function table lookup. */
794
795                 resm = method_vftbl_lookup(vftbl, m);
796         }
797
798         STATISTICS(jnicallXmethodnvokation());
799
800         (void) vm_call_method_jvalue(resm, o, args);
801 }
802
803
804 /* GetVersion ******************************************************************
805
806    Returns the major version number in the higher 16 bits and the
807    minor version number in the lower 16 bits.
808
809 *******************************************************************************/
810
811 jint _Jv_JNI_GetVersion(JNIEnv *env)
812 {
813         TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
814
815         /* We support JNI 1.6. */
816
817         return JNI_VERSION_1_6;
818 }
819
820
821 /* Class Operations ***********************************************************/
822
823 /* DefineClass *****************************************************************
824
825    Loads a class from a buffer of raw class data. The buffer
826    containing the raw class data is not referenced by the VM after the
827    DefineClass call returns, and it may be discarded if desired.
828
829 *******************************************************************************/
830
831 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
832                                                    const jbyte *buf, jsize bufLen)
833 {
834 #if defined(ENABLE_JAVASE)
835         utf             *u;
836         classloader     *cl;
837         classinfo       *c;
838         java_lang_Class *co;
839
840         TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
841
842         u  = utf_new_char(name);
843         cl = loader_hashtable_classloader_add((java_handle_t *) loader);
844
845         c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
846
847         co = LLNI_classinfo_wrap(c);
848
849         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
850 #else
851         vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
852
853         /* keep compiler happy */
854
855         return 0;
856 #endif
857 }
858
859
860 /* FindClass *******************************************************************
861
862    This function loads a locally-defined class. It searches the
863    directories and zip files specified by the CLASSPATH environment
864    variable for the class with the specified name.
865
866 *******************************************************************************/
867
868 jclass jni_FindClass(JNIEnv *env, const char *name)
869 {
870 #if defined(ENABLE_JAVASE)
871
872         utf             *u;
873         classinfo       *cc;
874         classinfo       *c;
875         java_lang_Class *co;
876
877         TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
878
879         /* FIXME If name is NULL we have a problem here. */
880
881         u = utf_new_char_classname((char *) name);
882
883         if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
884                 exceptions_throw_noclassdeffounderror(u);
885                 return NULL;
886         }
887
888         /* Check stacktrace for classloader, if one found use it,
889            otherwise use the system classloader. */
890
891         /* Quote from the JNI documentation:
892          
893            In the Java 2 Platform, FindClass locates the class loader
894            associated with the current native method.  If the native code
895            belongs to a system class, no class loader will be
896            involved. Otherwise, the proper class loader will be invoked to
897            load and link the named class. When FindClass is called through
898            the Invocation Interface, there is no current native method or
899            its associated class loader. In that case, the result of
900            ClassLoader.getBaseClassLoader is used." */
901
902         cc = stacktrace_get_current_class();
903
904         if (cc == NULL)
905                 c = load_class_from_sysloader(u);
906         else
907                 c = load_class_from_classloader(u, cc->classloader);
908
909         if (c == NULL) {
910                 resolve_handle_pending_exception(true);
911                 return NULL;
912         }
913
914         if (!link_class(c))
915                 return NULL;
916
917         co = LLNI_classinfo_wrap(c);
918
919         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
920
921 #elif defined(ENABLE_JAVAME_CLDC1_1)
922
923         utf       *u;
924         classinfo *c;
925
926         TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
927
928         u = utf_new_char_classname((char *) name);
929         c = load_class_bootstrap(u);
930
931         if (c == NULL) {
932                 resolve_handle_pending_exception(true);
933                 return NULL;
934         }
935
936         if (!link_class(c))
937                 return NULL;
938
939         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
940         
941 #else
942         vm_abort("jni_FindClass: not implemented in this configuration");
943
944         /* keep compiler happy */
945
946         return NULL;
947 #endif
948 }
949   
950
951 /* GetSuperclass ***************************************************************
952
953    If clazz represents any class other than the class Object, then
954    this function returns the object that represents the superclass of
955    the class specified by clazz.
956
957 *******************************************************************************/
958  
959 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
960 {
961         classinfo       *c;
962         classinfo       *super;
963         java_lang_Class *co;
964
965         TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
966
967         c = LLNI_classinfo_unwrap(sub);
968
969         if (c == NULL)
970                 return NULL;
971
972         super = class_get_superclass(c);
973
974         co = LLNI_classinfo_wrap(super);
975
976         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
977 }
978   
979  
980 /* IsAssignableFrom ************************************************************
981
982    Determines whether an object of sub can be safely cast to sup.
983
984 *******************************************************************************/
985
986 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
987 {
988         java_lang_Class *csup;
989         java_lang_Class *csub;
990
991         csup = (java_lang_Class *) sup;
992         csub = (java_lang_Class *) sub;
993
994         STATISTICS(jniinvokation());
995
996         return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
997 }
998
999
1000 /* Throw ***********************************************************************
1001
1002    Causes a java.lang.Throwable object to be thrown.
1003
1004 *******************************************************************************/
1005
1006 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1007 {
1008         java_handle_t *o;
1009
1010         STATISTICS(jniinvokation());
1011
1012         o = (java_handle_t *) obj;
1013
1014         exceptions_set_exception(o);
1015
1016         return JNI_OK;
1017 }
1018
1019
1020 /* ThrowNew ********************************************************************
1021
1022    Constructs an exception object from the specified class with the
1023    message specified by message and causes that exception to be
1024    thrown.
1025
1026 *******************************************************************************/
1027
1028 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
1029 {
1030         classinfo     *c;
1031         java_handle_t *o;
1032         java_handle_t *s;
1033
1034         STATISTICS(jniinvokation());
1035
1036         c = LLNI_classinfo_unwrap(clazz);
1037         if (msg == NULL)
1038                 msg = "";
1039         s = javastring_new_from_utf_string(msg);
1040
1041         /* instantiate exception object */
1042
1043         o = native_new_and_init_string(c, s);
1044
1045         if (o == NULL)
1046                 return -1;
1047
1048         exceptions_set_exception(o);
1049
1050         return 0;
1051 }
1052
1053
1054 /* ExceptionOccurred ***********************************************************
1055
1056    Determines if an exception is being thrown. The exception stays
1057    being thrown until either the native code calls ExceptionClear(),
1058    or the Java code handles the exception.
1059
1060 *******************************************************************************/
1061
1062 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1063 {
1064         java_handle_t *o;
1065
1066         TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1067
1068         o = exceptions_get_exception();
1069
1070         return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1071 }
1072
1073
1074 /* ExceptionDescribe ***********************************************************
1075
1076    Prints an exception and a backtrace of the stack to a system
1077    error-reporting channel, such as stderr. This is a convenience
1078    routine provided for debugging.
1079
1080 *******************************************************************************/
1081
1082 void jni_ExceptionDescribe(JNIEnv *env)
1083 {
1084         TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1085
1086         exceptions_print_stacktrace();
1087 }
1088
1089
1090 /* ExceptionClear **************************************************************
1091
1092    Clears any exception that is currently being thrown. If no
1093    exception is currently being thrown, this routine has no effect.
1094
1095 *******************************************************************************/
1096
1097 void jni_ExceptionClear(JNIEnv *env)
1098 {
1099         TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1100
1101         exceptions_clear_exception();
1102 }
1103
1104
1105 /* FatalError ******************************************************************
1106
1107    Raises a fatal error and does not expect the VM to recover. This
1108    function does not return.
1109
1110 *******************************************************************************/
1111
1112 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1113 {
1114         STATISTICS(jniinvokation());
1115
1116         /* this seems to be the best way */
1117
1118         vm_abort("JNI Fatal error: %s", msg);
1119 }
1120
1121
1122 /* PushLocalFrame **************************************************************
1123
1124    Creates a new local reference frame, in which at least a given
1125    number of local references can be created.
1126
1127 *******************************************************************************/
1128
1129 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1130 {
1131         STATISTICS(jniinvokation());
1132
1133         if (capacity <= 0)
1134                 return -1;
1135
1136         /* add new local reference frame to current table */
1137
1138         if (!localref_frame_push(capacity))
1139                 return -1;
1140
1141         return 0;
1142 }
1143
1144
1145 /* PopLocalFrame ***************************************************************
1146
1147    Pops off the current local reference frame, frees all the local
1148    references, and returns a local reference in the previous local
1149    reference frame for the given result object.
1150
1151 *******************************************************************************/
1152
1153 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1154 {
1155         STATISTICS(jniinvokation());
1156
1157         /* release all current local frames */
1158
1159         localref_frame_pop_all();
1160
1161         /* add local reference and return the value */
1162
1163         return _Jv_JNI_NewLocalRef(env, result);
1164 }
1165
1166
1167 /* DeleteLocalRef **************************************************************
1168
1169    Deletes the local reference pointed to by localRef.
1170
1171 *******************************************************************************/
1172
1173 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1174 {
1175         java_handle_t *o;
1176
1177         STATISTICS(jniinvokation());
1178
1179         o = (java_handle_t *) localRef;
1180
1181         if (o == NULL)
1182                 return;
1183
1184         /* delete the reference */
1185
1186         localref_del(o);
1187 }
1188
1189
1190 /* IsSameObject ****************************************************************
1191
1192    Tests whether two references refer to the same Java object.
1193
1194 *******************************************************************************/
1195
1196 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1197 {
1198         java_handle_t *o1;
1199         java_handle_t *o2;
1200         jboolean       result;
1201
1202         STATISTICS(jniinvokation());
1203
1204         o1 = (java_handle_t *) ref1;
1205         o2 = (java_handle_t *) ref2;
1206
1207         LLNI_CRITICAL_START;
1208
1209         if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1210                 result = JNI_TRUE;
1211         else
1212                 result = JNI_FALSE;
1213
1214         LLNI_CRITICAL_END;
1215
1216         return result;
1217 }
1218
1219
1220 /* NewLocalRef *****************************************************************
1221
1222    Creates a new local reference that refers to the same object as ref.
1223
1224 *******************************************************************************/
1225
1226 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1227 {
1228         java_handle_t *o;
1229         java_handle_t *localref;
1230
1231         STATISTICS(jniinvokation());
1232
1233         o = (java_handle_t *) ref;
1234
1235         if (o == NULL)
1236                 return NULL;
1237
1238         /* insert the reference */
1239
1240         localref = localref_add(LLNI_DIRECT(o));
1241
1242         return (jobject) localref;
1243 }
1244
1245
1246 /* EnsureLocalCapacity *********************************************************
1247
1248    Ensures that at least a given number of local references can be
1249    created in the current thread
1250
1251 *******************************************************************************/
1252
1253 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1254 {
1255         localref_table *lrt;
1256
1257         STATISTICS(jniinvokation());
1258
1259         /* get local reference table (thread specific) */
1260
1261         lrt = LOCALREFTABLE;
1262
1263         /* check if capacity elements are available in the local references table */
1264
1265         if ((lrt->used + capacity) > lrt->capacity)
1266                 return _Jv_JNI_PushLocalFrame(env, capacity);
1267
1268         return 0;
1269 }
1270
1271
1272 /* AllocObject *****************************************************************
1273
1274    Allocates a new Java object without invoking any of the
1275    constructors for the object. Returns a reference to the object.
1276
1277 *******************************************************************************/
1278
1279 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1280 {
1281         classinfo     *c;
1282         java_handle_t *o;
1283
1284         STATISTICS(jniinvokation());
1285
1286         c = LLNI_classinfo_unwrap(clazz);
1287
1288         if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1289                 exceptions_throw_instantiationexception(c);
1290                 return NULL;
1291         }
1292                 
1293         o = builtin_new(c);
1294
1295         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1296 }
1297
1298
1299 /* NewObject *******************************************************************
1300
1301    Programmers place all arguments that are to be passed to the
1302    constructor immediately following the methodID
1303    argument. NewObject() accepts these arguments and passes them to
1304    the Java method that the programmer wishes to invoke.
1305
1306 *******************************************************************************/
1307
1308 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1309 {
1310         java_handle_t *o;
1311         classinfo     *c;
1312         methodinfo    *m;
1313         va_list        ap;
1314
1315         STATISTICS(jniinvokation());
1316
1317         c = LLNI_classinfo_unwrap(clazz);
1318         m = (methodinfo *) methodID;
1319
1320         /* create object */
1321
1322         o = builtin_new(c);
1323         
1324         if (o == NULL)
1325                 return NULL;
1326
1327         /* call constructor */
1328
1329         va_start(ap, methodID);
1330         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1331         va_end(ap);
1332
1333         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1334 }
1335
1336
1337 /* NewObjectV ******************************************************************
1338
1339    Programmers place all arguments that are to be passed to the
1340    constructor in an args argument of type va_list that immediately
1341    follows the methodID argument. NewObjectV() accepts these
1342    arguments, and, in turn, passes them to the Java method that the
1343    programmer wishes to invoke.
1344
1345 *******************************************************************************/
1346
1347 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1348                                                    va_list args)
1349 {
1350         java_handle_t *o;
1351         classinfo     *c;
1352         methodinfo    *m;
1353
1354         STATISTICS(jniinvokation());
1355
1356         c = LLNI_classinfo_unwrap(clazz);
1357         m = (methodinfo *) methodID;
1358
1359         /* create object */
1360
1361         o = builtin_new(c);
1362         
1363         if (o == NULL)
1364                 return NULL;
1365
1366         /* call constructor */
1367
1368         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1369
1370         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1371 }
1372
1373
1374 /* NewObjectA ***************************************************************** 
1375
1376    Programmers place all arguments that are to be passed to the
1377    constructor in an args array of jvalues that immediately follows
1378    the methodID argument. NewObjectA() accepts the arguments in this
1379    array, and, in turn, passes them to the Java method that the
1380    programmer wishes to invoke.
1381
1382 *******************************************************************************/
1383
1384 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1385                                                    const jvalue *args)
1386 {
1387         java_handle_t *o;
1388         classinfo     *c;
1389         methodinfo    *m;
1390
1391         STATISTICS(jniinvokation());
1392
1393         c = LLNI_classinfo_unwrap(clazz);
1394         m = (methodinfo *) methodID;
1395
1396         /* create object */
1397
1398         o = builtin_new(c);
1399         
1400         if (o == NULL)
1401                 return NULL;
1402
1403         /* call constructor */
1404
1405         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1406
1407         return _Jv_JNI_NewLocalRef(env, (jobject) o);
1408 }
1409
1410
1411 /* GetObjectClass **************************************************************
1412
1413  Returns the class of an object.
1414
1415 *******************************************************************************/
1416
1417 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1418 {
1419         java_handle_t   *o;
1420         classinfo       *c;
1421         java_lang_Class *co;
1422
1423         STATISTICS(jniinvokation());
1424
1425         o = (java_handle_t *) obj;
1426
1427         if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1428                 return NULL;
1429
1430         LLNI_class_get(o, c);
1431
1432         co = LLNI_classinfo_wrap(c);
1433
1434         return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1435 }
1436
1437
1438 /* IsInstanceOf ****************************************************************
1439
1440    Tests whether an object is an instance of a class.
1441
1442 *******************************************************************************/
1443
1444 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1445 {
1446         java_lang_Class  *c;
1447         java_lang_Object *o;
1448
1449         STATISTICS(jniinvokation());
1450
1451         c = (java_lang_Class *) clazz;
1452         o = (java_lang_Object *) obj;
1453
1454         return _Jv_java_lang_Class_isInstance(c, o);
1455 }
1456
1457
1458 /* Reflection Support *********************************************************/
1459
1460 /* FromReflectedMethod *********************************************************
1461
1462    Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1463    object to a method ID.
1464   
1465 *******************************************************************************/
1466   
1467 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
1468 {
1469 #if defined(ENABLE_JAVASE)
1470         java_handle_t *o;
1471         classinfo     *c;
1472         methodinfo    *m;
1473         s4             slot;
1474
1475         STATISTICS(jniinvokation());
1476
1477         o = (java_handle_t *) method;
1478
1479         if (o == NULL)
1480                 return NULL;
1481         
1482         if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
1483                 java_lang_reflect_Method *rm;
1484
1485                 rm   = (java_lang_reflect_Method *) method;
1486                 LLNI_field_get_cls(rm, clazz, c);
1487                 LLNI_field_get_val(rm, slot , slot);
1488         }
1489         else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
1490                 java_lang_reflect_Constructor *rc;
1491
1492                 rc   = (java_lang_reflect_Constructor *) method;
1493                 LLNI_field_get_cls(rc, clazz, c);
1494                 LLNI_field_get_val(rc, slot , slot);
1495         }
1496         else
1497                 return NULL;
1498
1499         m = &(c->methods[slot]);
1500
1501         return (jmethodID) m;
1502 #else
1503         vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
1504
1505         /* keep compiler happy */
1506
1507         return NULL;
1508 #endif
1509 }
1510
1511
1512 /* FromReflectedField **********************************************************
1513
1514    Converts a java.lang.reflect.Field to a field ID.
1515
1516 *******************************************************************************/
1517  
1518 jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
1519 {
1520 #if defined(ENABLE_JAVASE)
1521         java_lang_reflect_Field *rf;
1522         classinfo               *c;
1523         fieldinfo               *f;
1524         int32_t                  slot;
1525
1526         STATISTICS(jniinvokation());
1527
1528         rf = (java_lang_reflect_Field *) field;
1529
1530         if (rf == NULL)
1531                 return NULL;
1532
1533         LLNI_field_get_cls(rf, clazz, c);
1534         LLNI_field_get_val(rf, slot , slot);
1535         f = &(c->fields[slot]);
1536
1537         return (jfieldID) f;
1538 #else
1539         vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
1540
1541         /* keep compiler happy */
1542
1543         return NULL;
1544 #endif
1545 }
1546
1547
1548 /* ToReflectedMethod ***********************************************************
1549
1550    Converts a method ID derived from cls to an instance of the
1551    java.lang.reflect.Method class or to an instance of the
1552    java.lang.reflect.Constructor class.
1553
1554 *******************************************************************************/
1555
1556 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1557                                                                   jboolean isStatic)
1558 {
1559 #if defined(ENABLE_JAVASE)
1560         methodinfo                    *m;
1561         java_lang_reflect_Constructor *rc;
1562         java_lang_reflect_Method      *rm;
1563
1564         TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1565
1566         m = (methodinfo *) methodID;
1567
1568         /* HotSpot does the same assert. */
1569
1570         assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1571
1572         if (m->name == utf_init) {
1573                 rc = reflect_constructor_new(m);
1574
1575                 return (jobject) rc;
1576         }
1577         else {
1578                 rm = reflect_method_new(m);
1579
1580                 return (jobject) rm;
1581         }
1582 #else
1583         vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1584
1585         /* keep compiler happy */
1586
1587         return NULL;
1588 #endif
1589 }
1590
1591
1592 /* ToReflectedField ************************************************************
1593
1594    Converts a field ID derived from cls to an instance of the
1595    java.lang.reflect.Field class.
1596
1597 *******************************************************************************/
1598
1599 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1600                                                                  jboolean isStatic)
1601 {
1602         STATISTICS(jniinvokation());
1603
1604         log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1605
1606         return NULL;
1607 }
1608
1609
1610 /* Calling Instance Methods ***************************************************/
1611
1612 /* GetMethodID *****************************************************************
1613
1614    Returns the method ID for an instance (nonstatic) method of a class
1615    or interface. The method may be defined in one of the clazz's
1616    superclasses and inherited by clazz. The method is determined by
1617    its name and signature.
1618
1619    GetMethodID() causes an uninitialized class to be initialized.
1620
1621 *******************************************************************************/
1622
1623 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1624                                                           const char *sig)
1625 {
1626         classinfo  *c;
1627         utf        *uname;
1628         utf        *udesc;
1629         methodinfo *m;
1630
1631         STATISTICS(jniinvokation());
1632
1633         c = LLNI_classinfo_unwrap(clazz);
1634
1635         if (c == NULL)
1636                 return NULL;
1637
1638         if (!(c->state & CLASS_INITIALIZED))
1639                 if (!initialize_class(c))
1640                         return NULL;
1641
1642         /* try to get the method of the class or one of it's superclasses */
1643
1644         uname = utf_new_char((char *) name);
1645         udesc = utf_new_char((char *) sig);
1646
1647         m = class_resolvemethod(c, uname, udesc);
1648
1649         if ((m == NULL) || (m->flags & ACC_STATIC)) {
1650                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1651
1652                 return NULL;
1653         }
1654
1655         return (jmethodID) m;
1656 }
1657
1658
1659 /* JNI-functions for calling instance methods *********************************/
1660
1661 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
1662 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
1663                                                                 jmethodID methodID, ...)    \
1664 {                                                           \
1665         java_handle_t *o;                                       \
1666         methodinfo    *m;                                       \
1667         va_list        ap;                                      \
1668         type           ret;                                     \
1669                                                             \
1670         o = (java_handle_t *) obj;                              \
1671         m = (methodinfo *) methodID;                            \
1672                                                             \
1673         va_start(ap, methodID);                                 \
1674         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1675         va_end(ap);                                             \
1676                                                             \
1677         return ret;                                             \
1678 }
1679
1680 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1681 JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
1682 JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
1683 JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
1684 JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
1685 JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
1686 JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
1687 JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
1688
1689
1690 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
1691 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
1692                                                                  jmethodID methodID, va_list args) \
1693 {                                                                  \
1694         java_handle_t *o;                                              \
1695         methodinfo    *m;                                              \
1696         type           ret;                                            \
1697                                                                    \
1698         o = (java_handle_t *) obj;                                     \
1699         m = (methodinfo *) methodID;                                   \
1700                                                                    \
1701         ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args);      \
1702                                                                    \
1703         return ret;                                                    \
1704 }
1705
1706 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1707 JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
1708 JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
1709 JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
1710 JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
1711 JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
1712 JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
1713 JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
1714
1715
1716 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
1717 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
1718                                                                  jmethodID methodID,           \
1719                                                                  const jvalue *args)           \
1720 {                                                              \
1721         java_handle_t *o;                                          \
1722         methodinfo    *m;                                          \
1723         type           ret;                                        \
1724                                                                \
1725         o = (java_handle_t *) obj;                                 \
1726         m = (methodinfo *) methodID;                               \
1727                                                                \
1728         ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1729                                                                \
1730         return ret;                                                \
1731 }
1732
1733 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1734 JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
1735 JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
1736 JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
1737 JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
1738 JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
1739 JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
1740 JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
1741
1742
1743 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1744                                                                  ...)
1745 {
1746         java_handle_t *o;
1747         methodinfo    *m;
1748         java_handle_t *ret;
1749         va_list        ap;
1750
1751         o = (java_handle_t *) obj;
1752         m = (methodinfo *) methodID;
1753
1754         va_start(ap, methodID);
1755         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1756         va_end(ap);
1757
1758         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1759 }
1760
1761
1762 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1763                                                                   va_list args)
1764 {
1765         java_handle_t *o;
1766         methodinfo    *m;
1767         java_handle_t *ret;
1768
1769         o = (java_handle_t *) obj;
1770         m = (methodinfo *) methodID;
1771
1772         ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1773
1774         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1775 }
1776
1777
1778 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1779                                                                   const jvalue *args)
1780 {
1781         java_handle_t *o;
1782         methodinfo    *m;
1783         java_handle_t *ret;
1784
1785         o = (java_handle_t *) obj;
1786         m = (methodinfo *) methodID;
1787
1788         ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1789
1790         return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1791 }
1792
1793
1794
1795 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1796 {
1797         java_handle_t *o;
1798         methodinfo    *m;
1799         va_list        ap;
1800
1801         o = (java_handle_t *) obj;
1802         m = (methodinfo *) methodID;
1803
1804         va_start(ap, methodID);
1805         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1806         va_end(ap);
1807 }
1808
1809
1810 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1811                                                          va_list args)
1812 {
1813         java_handle_t *o;
1814         methodinfo    *m;
1815
1816         o = (java_handle_t *) obj;
1817         m = (methodinfo *) methodID;
1818
1819         _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1820 }
1821
1822
1823 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1824                                                          const jvalue *args)
1825 {
1826         java_handle_t *o;
1827         methodinfo    *m;
1828
1829         o = (java_handle_t *) obj;
1830         m = (methodinfo *) methodID;
1831
1832         _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1833 }
1834
1835
1836
1837 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
1838 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
1839                                                                                   jclass clazz, jmethodID methodID, \
1840                                                                                   ...)                              \
1841 {                                                                           \
1842         java_handle_t *o;                                                       \
1843         classinfo     *c;                                                       \
1844         methodinfo    *m;                                                       \
1845         va_list        ap;                                                      \
1846         type           ret;                                                     \
1847                                                                             \
1848         o = (java_handle_t *) obj;                                              \
1849         c = LLNI_classinfo_unwrap(clazz);                                       \
1850         m = (methodinfo *) methodID;                                            \
1851                                                                             \
1852         va_start(ap, methodID);                                                 \
1853         ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
1854         va_end(ap);                                                             \
1855                                                                             \
1856         return ret;                                                             \
1857 }
1858
1859 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1860 JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
1861 JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
1862 JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
1863 JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
1864 JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
1865 JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
1866 JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
1867
1868
1869 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
1870 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
1871                                                                                    jclass clazz, jmethodID methodID, \
1872                                                                                    va_list args)                     \
1873 {                                                                            \
1874         java_handle_t *o;                                                        \
1875         classinfo     *c;                                                        \
1876         methodinfo    *m;                                                        \
1877         type           ret;                                                      \
1878                                                                              \
1879         o = (java_handle_t *) obj;                                               \
1880         c = LLNI_classinfo_unwrap(clazz);                                        \
1881         m = (methodinfo *) methodID;                                             \
1882                                                                              \
1883         ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
1884                                                                              \
1885         return ret;                                                              \
1886 }
1887
1888 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1889 JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
1890 JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
1891 JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
1892 JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
1893 JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
1894 JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
1895 JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
1896
1897
1898 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
1899 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
1900                                                                                    jclass clazz, jmethodID methodID, \
1901                                                                                    const jvalue *args)               \
1902 {                                                                            \
1903         log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
1904                                                                              \
1905         return 0;                                                                \
1906 }
1907
1908 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1909 JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
1910 JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
1911 JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
1912 JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
1913 JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
1914 JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
1915 JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
1916
1917 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1918                                                                                    jclass clazz, jmethodID methodID,
1919                                                                                    ...)
1920 {
1921         java_handle_t *o;
1922         classinfo     *c;
1923         methodinfo    *m;
1924         java_handle_t *r;
1925         va_list        ap;
1926
1927         o = (java_handle_t *) obj;
1928         c = LLNI_classinfo_unwrap(clazz);
1929         m = (methodinfo *) methodID;
1930
1931         va_start(ap, methodID);
1932         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1933         va_end(ap);
1934
1935         return _Jv_JNI_NewLocalRef(env, (jobject) r);
1936 }
1937
1938
1939 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1940                                                                                         jclass clazz, jmethodID methodID,
1941                                                                                         va_list args)
1942 {
1943         java_handle_t *o;
1944         classinfo     *c;
1945         methodinfo    *m;
1946         java_handle_t *r;
1947
1948         o = (java_handle_t *) obj;
1949         c = LLNI_classinfo_unwrap(clazz);
1950         m = (methodinfo *) methodID;
1951
1952         r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1953
1954         return _Jv_JNI_NewLocalRef(env, (jobject) r);
1955 }
1956
1957
1958 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1959                                                                                         jclass clazz, jmethodID methodID,
1960                                                                                         const jvalue *args)
1961 {
1962         log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1963
1964         return _Jv_JNI_NewLocalRef(env, NULL);
1965 }
1966
1967
1968 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1969                                                                           jmethodID methodID, ...)
1970 {
1971         java_handle_t *o;
1972         classinfo     *c;
1973         methodinfo    *m;
1974         va_list        ap;
1975
1976         o = (java_handle_t *) obj;
1977         c = LLNI_classinfo_unwrap(clazz);
1978         m = (methodinfo *) methodID;
1979
1980         va_start(ap, methodID);
1981         _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1982         va_end(ap);
1983 }
1984
1985
1986 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1987                                                                            jmethodID methodID, va_list args)
1988 {
1989         java_handle_t *o;
1990         classinfo     *c;
1991         methodinfo    *m;
1992
1993         o = (java_handle_t *) obj;
1994         c = LLNI_classinfo_unwrap(clazz);
1995         m = (methodinfo *) methodID;
1996
1997         _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1998 }
1999
2000
2001 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2002                                                                            jmethodID methodID, const jvalue * args)
2003 {       
2004         java_handle_t *o;
2005         classinfo     *c;
2006         methodinfo    *m;
2007
2008         o = (java_handle_t *) obj;
2009         c = LLNI_classinfo_unwrap(clazz);
2010         m = (methodinfo *) methodID;
2011
2012         _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2013 }
2014
2015
2016 /* Accessing Fields of Objects ************************************************/
2017
2018 /* GetFieldID ******************************************************************
2019
2020    Returns the field ID for an instance (nonstatic) field of a
2021    class. The field is specified by its name and signature. The
2022    Get<type>Field and Set<type>Field families of accessor functions
2023    use field IDs to retrieve object fields.
2024
2025 *******************************************************************************/
2026
2027 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2028                                                         const char *sig)
2029 {
2030         classinfo *c;
2031         fieldinfo *f;
2032         utf       *uname;
2033         utf       *udesc;
2034
2035         STATISTICS(jniinvokation());
2036
2037         c = LLNI_classinfo_unwrap(clazz);
2038
2039         /* XXX NPE check? */
2040
2041         uname = utf_new_char((char *) name);
2042         udesc = utf_new_char((char *) sig);
2043
2044         f = class_findfield(c, uname, udesc); 
2045         
2046         if (f == NULL)
2047                 exceptions_throw_nosuchfielderror(c, uname);  
2048
2049         return (jfieldID) f;
2050 }
2051
2052
2053 /* Get<type>Field Routines *****************************************************
2054
2055    This family of accessor routines returns the value of an instance
2056    (nonstatic) field of an object. The field to access is specified by
2057    a field ID obtained by calling GetFieldID().
2058
2059 *******************************************************************************/
2060
2061 #define GET_FIELD(o,type,f) \
2062     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2063
2064 #define JNI_GET_FIELD(name, type, intern)                                 \
2065 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2066 {                                                                         \
2067         intern ret;                                                           \
2068                                                                           \
2069         TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2070                                                                           \
2071         LLNI_CRITICAL_START;                                                  \
2072                                                                           \
2073         ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2074                                                                           \
2075         LLNI_CRITICAL_END;                                                    \
2076                                                                           \
2077         return (type) ret;                                                    \
2078 }
2079
2080 JNI_GET_FIELD(Boolean, jboolean, s4)
2081 JNI_GET_FIELD(Byte,    jbyte,    s4)
2082 JNI_GET_FIELD(Char,    jchar,    s4)
2083 JNI_GET_FIELD(Short,   jshort,   s4)
2084 JNI_GET_FIELD(Int,     jint,     s4)
2085 JNI_GET_FIELD(Long,    jlong,    s8)
2086 JNI_GET_FIELD(Float,   jfloat,   float)
2087 JNI_GET_FIELD(Double,  jdouble,  double)
2088
2089
2090 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2091 {
2092         java_handle_t *o;
2093
2094         TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2095
2096         LLNI_CRITICAL_START;
2097
2098         o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2099
2100         LLNI_CRITICAL_END;
2101
2102         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2103 }
2104
2105
2106 /* Set<type>Field Routines *****************************************************
2107
2108    This family of accessor routines sets the value of an instance
2109    (nonstatic) field of an object. The field to access is specified by
2110    a field ID obtained by calling GetFieldID().
2111
2112 *******************************************************************************/
2113
2114 #define SET_FIELD(o,type,f,value) \
2115     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2116
2117 #define JNI_SET_FIELD(name, type, intern)                                  \
2118 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
2119                                                           type value)                                  \
2120 {                                                                          \
2121         TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2122                                                                            \
2123         LLNI_CRITICAL_START;                                                   \
2124                                                                            \
2125         SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2126                                                                                \
2127         LLNI_CRITICAL_START;                                                   \
2128 }
2129
2130 JNI_SET_FIELD(Boolean, jboolean, s4)
2131 JNI_SET_FIELD(Byte,    jbyte,    s4)
2132 JNI_SET_FIELD(Char,    jchar,    s4)
2133 JNI_SET_FIELD(Short,   jshort,   s4)
2134 JNI_SET_FIELD(Int,     jint,     s4)
2135 JNI_SET_FIELD(Long,    jlong,    s8)
2136 JNI_SET_FIELD(Float,   jfloat,   float)
2137 JNI_SET_FIELD(Double,  jdouble,  double)
2138
2139
2140 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2141                                                         jobject value)
2142 {
2143         TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2144
2145         LLNI_CRITICAL_START;
2146
2147         SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2148
2149         LLNI_CRITICAL_END;
2150 }
2151
2152
2153 /* Calling Static Methods *****************************************************/
2154
2155 /* GetStaticMethodID ***********************************************************
2156
2157    Returns the method ID for a static method of a class. The method is
2158    specified by its name and signature.
2159
2160    GetStaticMethodID() causes an uninitialized class to be
2161    initialized.
2162
2163 *******************************************************************************/
2164
2165 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2166                                                                         const char *sig)
2167 {
2168         classinfo  *c;
2169         utf        *uname;
2170         utf        *udesc;
2171         methodinfo *m;
2172
2173         TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2174
2175         c = LLNI_classinfo_unwrap(clazz);
2176
2177         if (c == NULL)
2178                 return NULL;
2179
2180         if (!(c->state & CLASS_INITIALIZED))
2181                 if (!initialize_class(c))
2182                         return NULL;
2183
2184         /* try to get the static method of the class */
2185
2186         uname = utf_new_char((char *) name);
2187         udesc = utf_new_char((char *) sig);
2188
2189         m = class_resolvemethod(c, uname, udesc);
2190
2191         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2192                 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2193
2194                 return NULL;
2195         }
2196
2197         return (jmethodID) m;
2198 }
2199
2200
2201 #define JNI_CALL_STATIC_METHOD(name, type, intern)               \
2202 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2203                                                                           jmethodID methodID, ...)   \
2204 {                                                                \
2205         methodinfo *m;                                               \
2206         va_list     ap;                                              \
2207         type        res;                                             \
2208                                                                  \
2209         m = (methodinfo *) methodID;                                 \
2210                                                                  \
2211         va_start(ap, methodID);                                      \
2212         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
2213         va_end(ap);                                                  \
2214                                                                  \
2215         return res;                                                  \
2216 }
2217
2218 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2219 JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
2220 JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
2221 JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
2222 JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
2223 JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
2224 JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
2225 JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
2226
2227
2228 #define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
2229 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
2230                                                                            jmethodID methodID, va_list args) \
2231 {                                                                        \
2232         methodinfo *m;                                                       \
2233         type        res;                                                     \
2234                                                                          \
2235         m = (methodinfo *) methodID;                                         \
2236                                                                          \
2237         res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
2238                                                                          \
2239         return res;                                                          \
2240 }
2241
2242 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2243 JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
2244 JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
2245 JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
2246 JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
2247 JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
2248 JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
2249 JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
2250
2251
2252 #define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
2253 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
2254                                                                            jmethodID methodID, const jvalue *args) \
2255 {                                                                              \
2256         methodinfo *m;                                                             \
2257         type        res;                                                           \
2258                                                                                \
2259         m = (methodinfo *) methodID;                                               \
2260                                                                                \
2261         res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
2262                                                                                \
2263         return res;                                                                \
2264 }
2265
2266 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2267 JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
2268 JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
2269 JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
2270 JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
2271 JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
2272 JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
2273 JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
2274
2275
2276 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2277                                                                            jmethodID methodID, ...)
2278 {
2279         methodinfo    *m;
2280         java_handle_t *o;
2281         va_list        ap;
2282
2283         TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2284
2285         m = (methodinfo *) methodID;
2286
2287         va_start(ap, methodID);
2288         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2289         va_end(ap);
2290
2291         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2292 }
2293
2294
2295 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2296                                                                                 jmethodID methodID, va_list args)
2297 {
2298         methodinfo    *m;
2299         java_handle_t *o;
2300
2301         TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2302
2303         m = (methodinfo *) methodID;
2304
2305         o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2306
2307         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2308 }
2309
2310
2311 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2312                                                                                 jmethodID methodID, const jvalue *args)
2313 {
2314         methodinfo    *m;
2315         java_handle_t *o;
2316
2317         TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2318
2319         m = (methodinfo *) methodID;
2320
2321         o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2322
2323         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2324 }
2325
2326
2327 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2328                                                                   jmethodID methodID, ...)
2329 {
2330         methodinfo *m;
2331         va_list     ap;
2332
2333         TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2334
2335         m = (methodinfo *) methodID;
2336
2337         va_start(ap, methodID);
2338         _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2339         va_end(ap);
2340 }
2341
2342
2343 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2344                                                                    jmethodID methodID, va_list args)
2345 {
2346         methodinfo *m;
2347
2348         TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2349
2350         m = (methodinfo *) methodID;
2351
2352         _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2353 }
2354
2355
2356 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2357                                                                    jmethodID methodID, const jvalue * args)
2358 {
2359         methodinfo *m;
2360
2361         TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2362
2363         m = (methodinfo *) methodID;
2364
2365         _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2366 }
2367
2368
2369 /* Accessing Static Fields ****************************************************/
2370
2371 /* GetStaticFieldID ************************************************************
2372
2373    Returns the field ID for a static field of a class. The field is
2374    specified by its name and signature. The GetStatic<type>Field and
2375    SetStatic<type>Field families of accessor functions use field IDs
2376    to retrieve static fields.
2377
2378 *******************************************************************************/
2379
2380 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2381                                                                   const char *sig)
2382 {
2383         classinfo *c;
2384         fieldinfo *f;
2385         utf       *uname;
2386         utf       *usig;
2387
2388         STATISTICS(jniinvokation());
2389
2390         c = LLNI_classinfo_unwrap(clazz);
2391
2392         uname = utf_new_char((char *) name);
2393         usig  = utf_new_char((char *) sig);
2394
2395         f = class_findfield(c, uname, usig);
2396         
2397         if (f == NULL)
2398                 exceptions_throw_nosuchfielderror(c, uname);
2399
2400         return (jfieldID) f;
2401 }
2402
2403
2404 /* GetStatic<type>Field ********************************************************
2405
2406    This family of accessor routines returns the value of a static
2407    field of an object.
2408
2409 *******************************************************************************/
2410
2411 #define JNI_GET_STATIC_FIELD(name, type, field)                \
2412 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2413                                                                         jfieldID fieldID)          \
2414 {                                                              \
2415         classinfo *c;                                              \
2416         fieldinfo *f;                                              \
2417                                                                \
2418         STATISTICS(jniinvokation());                               \
2419                                                                \
2420         c = LLNI_classinfo_unwrap(clazz);                          \
2421         f = (fieldinfo *) fieldID;                                 \
2422                                                                \
2423         if (!(c->state & CLASS_INITIALIZED))                       \
2424                 if (!initialize_class(c))                              \
2425                         return 0;                                          \
2426                                                                \
2427         return f->value->field;                                    \
2428 }
2429
2430 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2431 JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
2432 JNI_GET_STATIC_FIELD(Char,    jchar,    i)
2433 JNI_GET_STATIC_FIELD(Short,   jshort,   i)
2434 JNI_GET_STATIC_FIELD(Int,     jint,     i)
2435 JNI_GET_STATIC_FIELD(Long,    jlong,    l)
2436 JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
2437 JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
2438
2439
2440 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2441                                                                          jfieldID fieldID)
2442 {
2443         classinfo     *c;
2444         fieldinfo     *f;
2445         java_handle_t *h;
2446
2447         STATISTICS(jniinvokation());
2448
2449         c = LLNI_classinfo_unwrap(clazz);
2450         f = (fieldinfo *) fieldID;
2451
2452         if (!(c->state & CLASS_INITIALIZED))
2453                 if (!initialize_class(c))
2454                         return NULL;
2455
2456         h = LLNI_WRAP(f->value->a);
2457
2458         return _Jv_JNI_NewLocalRef(env, (jobject) h);
2459 }
2460
2461
2462 /*  SetStatic<type>Field *******************************************************
2463
2464         This family of accessor routines sets the value of a static field
2465         of an object.
2466
2467 *******************************************************************************/
2468
2469 #define JNI_SET_STATIC_FIELD(name, type, field)                \
2470 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2471                                                                         jfieldID fieldID,          \
2472                                                                         type value)                \
2473 {                                                              \
2474         classinfo *c;                                              \
2475         fieldinfo *f;                                              \
2476                                                                \
2477         STATISTICS(jniinvokation());                               \
2478                                                                \
2479         c = LLNI_classinfo_unwrap(clazz);                          \
2480         f = (fieldinfo *) fieldID;                                 \
2481                                                                \
2482         if (!(c->state & CLASS_INITIALIZED))                       \
2483                 if (!initialize_class(c))                              \
2484                         return;                                            \
2485                                                                \
2486         f->value->field = value;                                   \
2487 }
2488
2489 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2490 JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
2491 JNI_SET_STATIC_FIELD(Char,    jchar,    i)
2492 JNI_SET_STATIC_FIELD(Short,   jshort,   i)
2493 JNI_SET_STATIC_FIELD(Int,     jint,     i)
2494 JNI_SET_STATIC_FIELD(Long,    jlong,    l)
2495 JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
2496 JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
2497
2498
2499 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2500                                                                   jobject value)
2501 {
2502         classinfo *c;
2503         fieldinfo *f;
2504
2505         STATISTICS(jniinvokation());
2506
2507         c = LLNI_classinfo_unwrap(clazz);
2508         f = (fieldinfo *) fieldID;
2509
2510         if (!(c->state & CLASS_INITIALIZED))
2511                 if (!initialize_class(c))
2512                         return;
2513
2514         f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2515 }
2516
2517
2518 /* String Operations **********************************************************/
2519
2520 /* NewString *******************************************************************
2521
2522    Create new java.lang.String object from an array of Unicode
2523    characters.
2524
2525 *******************************************************************************/
2526
2527 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2528 {
2529         java_lang_String        *s;
2530         java_handle_chararray_t *a;
2531         u4                       i;
2532
2533         STATISTICS(jniinvokation());
2534         
2535         s = (java_lang_String *) builtin_new(class_java_lang_String);
2536         a = builtin_newarray_char(len);
2537
2538         /* javastring or characterarray could not be created */
2539         if ((a == NULL) || (s == NULL))
2540                 return NULL;
2541
2542         /* copy text */
2543         for (i = 0; i < len; i++)
2544                 LLNI_array_direct(a, i) = buf[i];
2545
2546         LLNI_field_set_ref(s, value , a);
2547         LLNI_field_set_val(s, offset, 0);
2548         LLNI_field_set_val(s, count , len);
2549
2550         return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2551 }
2552
2553
2554 static jchar emptyStringJ[]={0,0};
2555
2556 /* GetStringLength *************************************************************
2557
2558    Returns the length (the count of Unicode characters) of a Java
2559    string.
2560
2561 *******************************************************************************/
2562
2563 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2564 {
2565         java_lang_String *s;
2566         jsize             len;
2567
2568         TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2569
2570         s = (java_lang_String *) str;
2571
2572         LLNI_field_get_val(s, count, len);
2573
2574         return len;
2575 }
2576
2577
2578 /********************  convertes javastring to u2-array ****************************/
2579         
2580 u2 *javastring_tou2(jstring so) 
2581 {
2582         java_lang_String        *s;
2583         java_handle_chararray_t *a;
2584         u2                      *stringbuffer;
2585         u4                       i;
2586         int32_t                  count;
2587         int32_t                  offset;
2588
2589         STATISTICS(jniinvokation());
2590         
2591         s = (java_lang_String *) so;
2592
2593         if (!s)
2594                 return NULL;
2595
2596         LLNI_field_get_ref(s, value, a);
2597
2598         if (!a)
2599                 return NULL;
2600
2601         LLNI_field_get_val(s, count, count);
2602         LLNI_field_get_val(s, offset, offset);
2603
2604         /* allocate memory */
2605
2606         stringbuffer = MNEW(u2, count + 1);
2607
2608         /* copy text */
2609
2610         for (i = 0; i < count; i++)
2611                 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2612         
2613         /* terminate string */
2614
2615         stringbuffer[i] = '\0';
2616
2617         return stringbuffer;
2618 }
2619
2620
2621 /* GetStringChars **************************************************************
2622
2623    Returns a pointer to the array of Unicode characters of the
2624    string. This pointer is valid until ReleaseStringChars() is called.
2625
2626 *******************************************************************************/
2627
2628 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2629 {       
2630         jchar *jc;
2631
2632         STATISTICS(jniinvokation());
2633
2634         jc = javastring_tou2(str);
2635
2636         if (jc) {
2637                 if (isCopy)
2638                         *isCopy = JNI_TRUE;
2639
2640                 return jc;
2641         }
2642
2643         if (isCopy)
2644                 *isCopy = JNI_TRUE;
2645
2646         return emptyStringJ;
2647 }
2648
2649
2650 /* ReleaseStringChars **********************************************************
2651
2652    Informs the VM that the native code no longer needs access to
2653    chars. The chars argument is a pointer obtained from string using
2654    GetStringChars().
2655
2656 *******************************************************************************/
2657
2658 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2659 {
2660         java_lang_String *s;
2661
2662         STATISTICS(jniinvokation());
2663
2664         if (chars == emptyStringJ)
2665                 return;
2666
2667         s = (java_lang_String *) str;
2668
2669         MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2670 }
2671
2672
2673 /* NewStringUTF ****************************************************************
2674
2675    Constructs a new java.lang.String object from an array of UTF-8
2676    characters.
2677
2678 *******************************************************************************/
2679
2680 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2681 {
2682         java_lang_String *s;
2683
2684         TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2685
2686         s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2687
2688     return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2689 }
2690
2691
2692 /****************** returns the utf8 length in bytes of a string *******************/
2693
2694 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2695 {   
2696         java_lang_String *s;
2697         s4                length;
2698
2699         TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2700
2701         s = (java_lang_String *) string;
2702
2703         length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2704
2705         return length;
2706 }
2707
2708
2709 /* GetStringUTFChars ***********************************************************
2710
2711    Returns a pointer to an array of UTF-8 characters of the
2712    string. This array is valid until it is released by
2713    ReleaseStringUTFChars().
2714
2715 *******************************************************************************/
2716
2717 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2718                                                                           jboolean *isCopy)
2719 {
2720         utf *u;
2721
2722         STATISTICS(jniinvokation());
2723
2724         if (string == NULL)
2725                 return "";
2726
2727         if (isCopy)
2728                 *isCopy = JNI_TRUE;
2729         
2730         u = javastring_toutf((java_handle_t *) string, false);
2731
2732         if (u != NULL)
2733                 return u->text;
2734
2735         return "";
2736 }
2737
2738
2739 /* ReleaseStringUTFChars *******************************************************
2740
2741    Informs the VM that the native code no longer needs access to
2742    utf. The utf argument is a pointer derived from string using
2743    GetStringUTFChars().
2744
2745 *******************************************************************************/
2746
2747 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2748 {
2749         STATISTICS(jniinvokation());
2750
2751     /* XXX we don't release utf chars right now, perhaps that should be done 
2752            later. Since there is always one reference the garbage collector will
2753            never get them */
2754 }
2755
2756
2757 /* Array Operations ***********************************************************/
2758
2759 /* GetArrayLength **************************************************************
2760
2761    Returns the number of elements in the array.
2762
2763 *******************************************************************************/
2764
2765 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2766 {
2767         java_handle_t *a;
2768         jsize          size;
2769
2770         TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2771
2772         a = (java_handle_t *) array;
2773
2774         size = LLNI_array_size(a);
2775
2776         return size;
2777 }
2778
2779
2780 /* NewObjectArray **************************************************************
2781
2782    Constructs a new array holding objects in class elementClass. All
2783    elements are initially set to initialElement.
2784
2785 *******************************************************************************/
2786
2787 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2788                                                                         jclass elementClass, jobject initialElement)
2789 {
2790         classinfo                 *c;
2791         java_handle_t             *o;
2792         java_handle_objectarray_t *oa;
2793         s4                         i;
2794
2795         STATISTICS(jniinvokation());
2796
2797         c = LLNI_classinfo_unwrap(elementClass);
2798         o = (java_handle_t *) initialElement;
2799
2800         if (length < 0) {
2801                 exceptions_throw_negativearraysizeexception();
2802                 return NULL;
2803         }
2804
2805     oa = builtin_anewarray(length, c);
2806
2807         if (oa == NULL)
2808                 return NULL;
2809
2810         /* set all elements to initialElement */
2811
2812         for (i = 0; i < length; i++)
2813                 array_objectarray_element_set(oa, i, o);
2814
2815         return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2816 }
2817
2818
2819 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2820                                                                           jsize index)
2821 {
2822         java_handle_objectarray_t *oa;
2823         java_handle_t             *o;
2824
2825         STATISTICS(jniinvokation());
2826
2827         oa = (java_handle_objectarray_t *) array;
2828
2829         if (index >= LLNI_array_size(oa)) {
2830                 exceptions_throw_arrayindexoutofboundsexception();
2831                 return NULL;
2832         }
2833
2834         o = array_objectarray_element_get(oa, index);
2835
2836         return _Jv_JNI_NewLocalRef(env, (jobject) o);
2837 }
2838
2839
2840 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2841                                                                    jsize index, jobject val)
2842 {
2843         java_handle_objectarray_t *oa;
2844         java_handle_t             *o;
2845
2846         STATISTICS(jniinvokation());
2847
2848         oa = (java_handle_objectarray_t *) array;
2849         o  = (java_handle_t *) val;
2850
2851         if (index >= LLNI_array_size(oa)) {
2852                 exceptions_throw_arrayindexoutofboundsexception();
2853                 return;
2854         }
2855
2856         /* check if the class of value is a subclass of the element class
2857            of the array */
2858
2859         if (!builtin_canstore(oa, o))
2860                 return;
2861
2862         array_objectarray_element_set(oa, index, o);
2863 }
2864
2865
2866 #define JNI_NEW_ARRAY(name, type, intern)                \
2867 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
2868 {                                                        \
2869         java_handle_##intern##array_t *a;                    \
2870                                                          \
2871         STATISTICS(jniinvokation());                         \
2872                                                          \
2873         if (len < 0) {                                       \
2874                 exceptions_throw_negativearraysizeexception();   \
2875                 return NULL;                                     \
2876         }                                                    \
2877                                                          \
2878         a = builtin_newarray_##intern(len);                  \
2879                                                          \
2880         return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2881 }
2882
2883 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2884 JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
2885 JNI_NEW_ARRAY(Char,    jcharArray,    char)
2886 JNI_NEW_ARRAY(Short,   jshortArray,   byte)
2887 JNI_NEW_ARRAY(Int,     jintArray,     int)
2888 JNI_NEW_ARRAY(Long,    jlongArray,    long)
2889 JNI_NEW_ARRAY(Float,   jfloatArray,   float)
2890 JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
2891
2892
2893 /* Get<PrimitiveType>ArrayElements *********************************************
2894
2895    A family of functions that returns the body of the primitive array.
2896
2897 *******************************************************************************/
2898
2899 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
2900 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2901                                                                                  jboolean *isCopy)             \
2902 {                                                                      \
2903         java_handle_##intern##array_t *a;                                  \
2904                                                                        \
2905         TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2906                                                                        \
2907         a = (java_handle_##intern##array_t *) array;                       \
2908                                                                        \
2909         if (isCopy)                                                        \
2910                 *isCopy = JNI_FALSE;                                           \
2911                                                                        \
2912         return (type *) LLNI_array_data(a);                                \
2913 }
2914
2915 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2916 JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
2917 JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
2918 JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
2919 JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
2920 JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
2921 JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
2922 JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
2923
2924
2925 /* Release<PrimitiveType>ArrayElements *****************************************
2926
2927    A family of functions that informs the VM that the native code no
2928    longer needs access to elems. The elems argument is a pointer
2929    derived from array using the corresponding
2930    Get<PrimitiveType>ArrayElements() function. If necessary, this
2931    function copies back all changes made to elems to the original
2932    array.
2933
2934 *******************************************************************************/
2935
2936 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
2937 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
2938                                                                                   type *elems, jint mode)          \
2939 {                                                                          \
2940         java_handle_##intern##array_t *a;                                      \
2941                                                                            \
2942         STATISTICS(jniinvokation());                                           \
2943                                                                            \
2944         a = (java_handle_##intern##array_t *) array;                           \
2945                                                                            \
2946         if (elems != (type *) LLNI_array_data(a)) {                            \
2947                 switch (mode) {                                                    \
2948                 case JNI_COMMIT:                                                   \
2949                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2950                         break;                                                         \
2951                 case 0:                                                            \
2952                         MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
2953                         /* XXX TWISTI how should it be freed? */                       \
2954                         break;                                                         \
2955                 case JNI_ABORT:                                                    \
2956                         /* XXX TWISTI how should it be freed? */                       \
2957                         break;                                                         \
2958                 }                                                                  \
2959         }                                                                      \
2960 }
2961
2962 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2963 JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
2964 JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
2965 JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
2966 JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
2967 JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
2968 JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
2969 JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
2970
2971
2972 /*  Get<PrimitiveType>ArrayRegion **********************************************
2973
2974         A family of functions that copies a region of a primitive array
2975         into a buffer.
2976
2977 *******************************************************************************/
2978
2979 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
2980 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
2981                                                                         jsize start, jsize len, type *buf)  \
2982 {                                                                       \
2983         java_handle_##intern##array_t *a;                                   \
2984                                                                         \
2985         TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2986                                                                         \
2987         a = (java_handle_##intern##array_t *) array;                        \
2988                                                                         \
2989         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
2990                 exceptions_throw_arrayindexoutofboundsexception();              \
2991         else                                                                \
2992                 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
2993 }
2994
2995 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2996 JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
2997 JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
2998 JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
2999 JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
3000 JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
3001 JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
3002 JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
3003
3004
3005 /*  Set<PrimitiveType>ArrayRegion **********************************************
3006
3007         A family of functions that copies back a region of a primitive
3008         array from a buffer.
3009
3010 *******************************************************************************/
3011
3012 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
3013 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
3014                                                                         jsize start, jsize len, const type *buf) \
3015 {                                                                            \
3016         java_handle_##intern##array_t *a;                                        \
3017                                                                              \
3018         STATISTICS(jniinvokation());                                             \
3019                                                                              \
3020         a = (java_handle_##intern##array_t *) array;                             \
3021                                                                              \
3022         if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
3023                 exceptions_throw_arrayindexoutofboundsexception();                   \
3024         else                                                                     \
3025                 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
3026 }
3027
3028 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3029 JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
3030 JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
3031 JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
3032 JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
3033 JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
3034 JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
3035 JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
3036
3037
3038 /* Registering Native Methods *************************************************/
3039
3040 /* RegisterNatives *************************************************************
3041
3042    Registers native methods with the class specified by the clazz
3043    argument. The methods parameter specifies an array of
3044    JNINativeMethod structures that contain the names, signatures, and
3045    function pointers of the native methods. The nMethods parameter
3046    specifies the number of native methods in the array.
3047
3048 *******************************************************************************/
3049
3050 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3051                                                          const JNINativeMethod *methods, jint nMethods)
3052 {
3053         classinfo *c;
3054
3055         STATISTICS(jniinvokation());
3056
3057         c = LLNI_classinfo_unwrap(clazz);
3058
3059         /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3060         if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
3061         */
3062
3063         native_method_register(c->name, methods, nMethods);
3064
3065     return 0;
3066 }
3067
3068
3069 /* UnregisterNatives ***********************************************************
3070
3071    Unregisters native methods of a class. The class goes back to the
3072    state before it was linked or registered with its native method
3073    functions.
3074
3075    This function should not be used in normal native code. Instead, it
3076    provides special programs a way to reload and relink native
3077    libraries.
3078
3079 *******************************************************************************/
3080
3081 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3082 {
3083         STATISTICS(jniinvokation());
3084
3085         /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3086
3087     log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3088
3089     return 0;
3090 }
3091
3092
3093 /* Monitor Operations *********************************************************/
3094
3095 /* MonitorEnter ****************************************************************
3096
3097    Enters the monitor associated with the underlying Java object
3098    referred to by obj.
3099
3100 *******************************************************************************/
3101
3102 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3103 {
3104         STATISTICS(jniinvokation());
3105
3106         if (obj == NULL) {
3107                 exceptions_throw_nullpointerexception();
3108                 return JNI_ERR;
3109         }
3110
3111         LOCK_MONITOR_ENTER(obj);
3112
3113         return JNI_OK;
3114 }
3115
3116
3117 /* MonitorExit *****************************************************************
3118
3119    The current thread must be the owner of the monitor associated with
3120    the underlying Java object referred to by obj. The thread
3121    decrements the counter indicating the number of times it has
3122    entered this monitor. If the value of the counter becomes zero, the
3123    current thread releases the monitor.
3124
3125 *******************************************************************************/
3126
3127 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3128 {
3129         STATISTICS(jniinvokation());
3130
3131         if (obj == NULL) {
3132                 exceptions_throw_nullpointerexception();
3133                 return JNI_ERR;
3134         }
3135
3136         LOCK_MONITOR_EXIT(obj);
3137
3138         return JNI_OK;
3139 }
3140
3141
3142 /* JavaVM Interface ***********************************************************/
3143
3144 /* GetJavaVM *******************************************************************
3145
3146    Returns the Java VM interface (used in the Invocation API)
3147    associated with the current thread. The result is placed at the
3148    location pointed to by the second argument, vm.
3149
3150 *******************************************************************************/
3151
3152 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3153 {
3154         STATISTICS(jniinvokation());
3155
3156     *vm = (JavaVM *) _Jv_jvm;
3157
3158         return 0;
3159 }
3160
3161
3162 /* GetStringRegion *************************************************************
3163
3164    Copies len number of Unicode characters beginning at offset start
3165    to the given buffer buf.
3166
3167    Throws StringIndexOutOfBoundsException on index overflow.
3168
3169 *******************************************************************************/
3170
3171 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3172                                                          jchar *buf)
3173 {
3174         java_lang_String        *s;
3175         java_handle_chararray_t *ca;
3176
3177         STATISTICS(jniinvokation());
3178
3179         s  = (java_lang_String *) str;
3180         LLNI_field_get_ref(s, value, ca);
3181
3182         if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3183                 (start + len > LLNI_field_direct(s, count))) {
3184                 exceptions_throw_stringindexoutofboundsexception();
3185                 return;
3186         }
3187
3188         MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3189 }
3190
3191
3192 /* GetStringUTFRegion **********************************************************
3193
3194     Translates len number of Unicode characters beginning at offset
3195     start into UTF-8 format and place the result in the given buffer
3196     buf.
3197
3198     Throws StringIndexOutOfBoundsException on index overflow. 
3199
3200 *******************************************************************************/
3201
3202 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3203                                                                 jsize len, char *buf)
3204 {
3205         java_lang_String        *s;
3206         java_handle_chararray_t *ca;
3207         s4                       i;
3208         int32_t                  count;
3209         int32_t                  offset;
3210
3211         TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3212
3213         s  = (java_lang_String *) str;
3214         LLNI_field_get_ref(s, value, ca);
3215         LLNI_field_get_val(s, count, count);
3216         LLNI_field_get_val(s, offset, offset);
3217
3218         if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3219                 exceptions_throw_stringindexoutofboundsexception();
3220                 return;
3221         }
3222
3223         for (i = 0; i < len; i++)
3224                 buf[i] = LLNI_array_direct(ca, offset + start + i);
3225
3226         buf[i] = '\0';
3227 }
3228
3229
3230 /* GetPrimitiveArrayCritical ***************************************************
3231
3232    Obtain a direct pointer to array elements.
3233
3234 *******************************************************************************/
3235
3236 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3237                                                                                 jboolean *isCopy)
3238 {
3239         java_handle_bytearray_t *ba;
3240         jbyte                   *bp;
3241
3242         ba = (java_handle_bytearray_t *) array;
3243
3244         /* do the same as Kaffe does */
3245
3246         bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3247
3248         return (void *) bp;
3249 }
3250
3251
3252 /* ReleasePrimitiveArrayCritical ***********************************************
3253
3254    No specific documentation.
3255
3256 *******************************************************************************/
3257
3258 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3259                                                                                    void *carray, jint mode)
3260 {
3261         STATISTICS(jniinvokation());
3262
3263         /* do the same as Kaffe does */
3264
3265         _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3266                                                                          mode);
3267 }
3268
3269
3270 /* GetStringCritical ***********************************************************
3271
3272    The semantics of these two functions are similar to the existing
3273    Get/ReleaseStringChars functions.
3274
3275 *******************************************************************************/
3276
3277 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3278                                                                            jboolean *isCopy)
3279 {
3280         STATISTICS(jniinvokation());
3281
3282         return _Jv_JNI_GetStringChars(env, string, isCopy);
3283 }
3284
3285
3286 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3287                                                                    const jchar *cstring)
3288 {
3289         STATISTICS(jniinvokation());
3290
3291         _Jv_JNI_ReleaseStringChars(env, string, cstring);
3292 }
3293
3294
3295 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3296 {
3297         TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3298
3299         return obj;
3300 }
3301
3302
3303 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3304 {
3305         TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3306 }
3307
3308
3309 /* NewGlobalRef ****************************************************************
3310
3311    Creates a new global reference to the object referred to by the obj
3312    argument.
3313
3314 *******************************************************************************/
3315     
3316 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3317 {
3318         hashtable_global_ref_entry *gre;
3319         u4   key;                           /* hashkey                            */
3320         u4   slot;                          /* slot in hashtable                  */
3321         java_handle_t *o;
3322
3323         STATISTICS(jniinvokation());
3324
3325         o = (java_handle_t *) obj;
3326
3327         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3328
3329         LLNI_CRITICAL_START;
3330
3331         /* normally addresses are aligned to 4, 8 or 16 bytes */
3332
3333         key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3334         slot = key & (hashtable_global_ref->size - 1);
3335         gre  = hashtable_global_ref->ptr[slot];
3336         
3337         /* search external hash chain for the entry */
3338
3339         while (gre) {
3340                 if (gre->o == LLNI_DIRECT(o)) {
3341                         /* global object found, increment the reference */
3342
3343                         gre->refs++;
3344
3345                         break;
3346                 }
3347
3348                 gre = gre->hashlink;                /* next element in external chain */
3349         }
3350
3351         LLNI_CRITICAL_END;
3352
3353         /* global ref not found, create a new one */
3354
3355         if (gre == NULL) {
3356                 gre = NEW(hashtable_global_ref_entry);
3357
3358 #if defined(ENABLE_GC_CACAO)
3359                 /* register global ref with the GC */
3360
3361                 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3362 #endif
3363
3364                 LLNI_CRITICAL_START;
3365
3366                 gre->o    = LLNI_DIRECT(o);
3367                 gre->refs = 1;
3368
3369                 LLNI_CRITICAL_END;
3370
3371                 /* insert entry into hashtable */
3372
3373                 gre->hashlink = hashtable_global_ref->ptr[slot];
3374
3375                 hashtable_global_ref->ptr[slot] = gre;
3376
3377                 /* update number of hashtable-entries */
3378
3379                 hashtable_global_ref->entries++;
3380         }
3381
3382         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3383
3384 #if defined(ENABLE_HANDLES)
3385         return gre;
3386 #else
3387         return obj;
3388 #endif
3389 }
3390
3391
3392 /* DeleteGlobalRef *************************************************************
3393
3394    Deletes the global reference pointed to by globalRef.
3395
3396 *******************************************************************************/
3397
3398 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3399 {
3400         hashtable_global_ref_entry *gre;
3401         hashtable_global_ref_entry *prevgre;
3402         u4   key;                           /* hashkey                            */
3403         u4   slot;                          /* slot in hashtable                  */
3404         java_handle_t              *o;
3405
3406         STATISTICS(jniinvokation());
3407
3408         o = (java_handle_t *) globalRef;
3409
3410         LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3411
3412         LLNI_CRITICAL_START;
3413
3414         /* normally addresses are aligned to 4, 8 or 16 bytes */
3415
3416         key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3417         slot = key & (hashtable_global_ref->size - 1);
3418         gre  = hashtable_global_ref->ptr[slot];
3419
3420         /* initialize prevgre */
3421
3422         prevgre = NULL;
3423
3424         /* search external hash chain for the entry */
3425
3426         while (gre) {
3427                 if (gre->o == LLNI_DIRECT(o)) {
3428                         /* global object found, decrement the reference count */
3429
3430                         gre->refs--;
3431
3432                         /* if reference count is 0, remove the entry */
3433
3434                         if (gre->refs == 0) {
3435                                 /* special handling if it's the first in the chain */
3436
3437                                 if (prevgre == NULL)
3438                                         hashtable_global_ref->ptr[slot] = gre->hashlink;
3439                                 else
3440                                         prevgre->hashlink = gre->hashlink;
3441
3442 #if defined(ENABLE_GC_CACAO)
3443                                 /* unregister global ref with the GC */
3444
3445                                 gc_reference_unregister(&(gre->o));
3446 #endif
3447
3448                                 FREE(gre, hashtable_global_ref_entry);
3449                         }
3450
3451                         LLNI_CRITICAL_END;
3452
3453                         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3454
3455                         return;
3456                 }
3457
3458                 prevgre = gre;                    /* save current pointer for removal */
3459                 gre     = gre->hashlink;            /* next element in external chain */
3460         }
3461
3462         log_println("JNI-DeleteGlobalRef: global reference not found");
3463
3464         LLNI_CRITICAL_END;
3465
3466         LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3467 }
3468
3469
3470 /* ExceptionCheck **************************************************************
3471
3472    Returns JNI_TRUE when there is a pending exception; otherwise,
3473    returns JNI_FALSE.
3474
3475 *******************************************************************************/
3476
3477 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3478 {
3479         java_handle_t *o;
3480
3481         STATISTICS(jniinvokation());
3482
3483         o = exceptions_get_exception();
3484
3485         return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3486 }
3487
3488
3489 /* New JNI 1.4 functions ******************************************************/
3490
3491 /* NewDirectByteBuffer *********************************************************
3492
3493    Allocates and returns a direct java.nio.ByteBuffer referring to the
3494    block of memory starting at the memory address address and
3495    extending capacity bytes.
3496
3497 *******************************************************************************/
3498
3499 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3500 {
3501 #if defined(ENABLE_JAVASE)
3502 # if defined(WITH_CLASSPATH_GNU)
3503         java_handle_t           *nbuf;
3504
3505 # if SIZEOF_VOID_P == 8
3506         gnu_classpath_Pointer64 *paddress;
3507 # else
3508         gnu_classpath_Pointer32 *paddress;
3509 # endif
3510
3511         TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3512
3513         /* alocate a gnu.classpath.Pointer{32,64} object */
3514
3515 # if SIZEOF_VOID_P == 8
3516         if (!(paddress = (gnu_classpath_Pointer64 *)
3517                   builtin_new(class_gnu_classpath_Pointer64)))
3518 # else
3519         if (!(paddress = (gnu_classpath_Pointer32 *)
3520                   builtin_new(class_gnu_classpath_Pointer32)))
3521 # endif
3522                 return NULL;
3523
3524         /* fill gnu.classpath.Pointer{32,64} with address */
3525
3526         LLNI_field_set_val(paddress, data, (ptrint) address);
3527
3528         /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3529
3530         nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3531                                                          (jmethodID) dbbirw_init, NULL, paddress,
3532                                                          (jint) capacity, (jint) capacity, (jint) 0);
3533
3534         /* add local reference and return the value */
3535
3536         return _Jv_JNI_NewLocalRef(env, nbuf);
3537
3538 # elif defined(WITH_CLASSPATH_SUN)
3539
3540         jobject o;
3541         int64_t addr;
3542         int32_t cap;
3543
3544         TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3545
3546         /* Be paranoid about address sign-extension. */
3547
3548         addr = (int64_t) ((uintptr_t) address);
3549         cap  = (int32_t) capacity;
3550
3551         o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3552                                                   (jmethodID) dbb_init, addr, cap);
3553
3554         /* Add local reference and return the value. */
3555
3556         return _Jv_JNI_NewLocalRef(env, o);
3557
3558 # else
3559 #  error unknown classpath configuration
3560 # endif
3561
3562 #else
3563         vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3564
3565         /* keep compiler happy */
3566
3567         return NULL;
3568 #endif
3569 }
3570
3571
3572 /* GetDirectBufferAddress ******************************************************
3573
3574    Fetches and returns the starting address of the memory region
3575    referenced by the given direct java.nio.Buffer.
3576
3577 *******************************************************************************/
3578
3579 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3580 {
3581 #if defined(ENABLE_JAVASE)
3582         java_handle_t                 *h;
3583
3584 # if defined(WITH_CLASSPATH_GNU)
3585
3586         java_nio_DirectByteBufferImpl *nbuf;
3587         gnu_classpath_Pointer         *po;
3588 #  if SIZEOF_VOID_P == 8
3589         gnu_classpath_Pointer64       *paddress;
3590         int64_t                        address;
3591 #  else
3592         gnu_classpath_Pointer32       *paddress;
3593         int32_t                        address;
3594 #  endif
3595         void                          *p;
3596
3597         TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3598
3599         /* Prevent compiler warning. */
3600
3601         h = (java_handle_t *) buf;
3602
3603         if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3604                 return NULL;
3605
3606         nbuf = (java_nio_DirectByteBufferImpl *) buf;
3607
3608         LLNI_field_get_ref(nbuf, address, po);
3609
3610 #  if SIZEOF_VOID_P == 8
3611         paddress = (gnu_classpath_Pointer64 *) po;
3612 #  else
3613         paddress = (gnu_classpath_Pointer32 *) po;
3614 #  endif
3615
3616         if (paddress == NULL)
3617                 return NULL;
3618
3619         LLNI_field_get_val(paddress, data, address);
3620
3621         p = (void *) (intptr_t) address;
3622
3623         return p;
3624
3625 # elif defined(WITH_CLASSPATH_SUN)
3626
3627         java_nio_Buffer *o;
3628         int64_t          address;
3629         void            *p;
3630
3631         TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3632
3633         /* Prevent compiler warning. */
3634
3635         h = (java_handle_t *) buf;
3636
3637         if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3638                 return NULL;
3639
3640         o = (java_nio_Buffer *) buf;
3641
3642         LLNI_field_get_val(o, address, address);
3643
3644         p = (void *) (intptr_t) address;
3645
3646         return p;
3647
3648 # else
3649 #  error unknown classpath configuration
3650 # endif
3651
3652 #else
3653
3654         vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3655
3656         /* keep compiler happy */
3657
3658         return NULL;
3659
3660 #endif
3661 }
3662
3663
3664 /* GetDirectBufferCapacity *****************************************************
3665
3666    Fetches and returns the capacity in bytes of the memory region
3667    referenced by the given direct java.nio.Buffer.
3668
3669 *******************************************************************************/
3670
3671 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3672 {
3673 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3674         java_handle_t   *o;
3675         java_nio_Buffer *nbuf;
3676         jlong            capacity;
3677
3678         STATISTICS(jniinvokation());
3679
3680         o = (java_handle_t *) buf;
3681
3682         if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3683                 return -1;
3684
3685         nbuf = (java_nio_Buffer *) o;
3686
3687         LLNI_field_get_val(nbuf, cap, capacity);
3688
3689         return capacity;
3690 #else
3691         vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3692
3693         /* keep compiler happy */
3694
3695         return 0;
3696 #endif
3697 }
3698
3699
3700 /* GetObjectRefType ************************************************************
3701
3702    Returns the type of the object referred to by the obj argument. The
3703    argument obj can either be a local, global or weak global
3704    reference.
3705
3706 *******************************************************************************/
3707
3708 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3709 {
3710         log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3711
3712         return -1;
3713 }
3714
3715
3716 /* DestroyJavaVM ***************************************************************
3717
3718    Unloads a Java VM and reclaims its resources. Only the main thread
3719    can unload the VM. The system waits until the main thread is only
3720    remaining user thread before it destroys the VM.
3721
3722 *******************************************************************************/
3723
3724 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3725 {
3726         int status;
3727
3728         TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3729
3730         if (vm_created == false)
3731                 return JNI_ERR;
3732
3733     status = vm_destroy(vm);
3734
3735         return status;
3736 }
3737
3738
3739 /* AttachCurrentThread *********************************************************
3740
3741    Attaches the current thread to a Java VM. Returns a JNI interface
3742    pointer in the JNIEnv argument.
3743
3744    Trying to attach a thread that is already attached is a no-op.
3745
3746    A native thread cannot be attached simultaneously to two Java VMs.
3747
3748    When a thread is attached to the VM, the context class loader is
3749    the bootstrap loader.
3750
3751 *******************************************************************************/
3752
3753 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3754 {
3755 #if defined(ENABLE_THREADS)
3756         JavaVMAttachArgs *vm_aargs;
3757         bool              result;
3758
3759     /* If the current thread has already been attached, this operation
3760            is a no-op. */
3761
3762         result = thread_current_is_attached();
3763
3764         if (result == true) {
3765                 *p_env = _Jv_env;
3766
3767                 return JNI_OK;
3768         }
3769
3770         vm_aargs = (JavaVMAttachArgs *) thr_args;
3771
3772         if (vm_aargs != NULL) {
3773                 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3774                         (vm_aargs->version != JNI_VERSION_1_4))
3775                         return JNI_EVERSION;
3776         }
3777
3778         if (!threads_attach_current_thread(vm_aargs, false))
3779                 return JNI_ERR;
3780
3781         if (!localref_table_init())
3782                 return JNI_ERR;
3783 #endif
3784
3785         *p_env = _Jv_env;
3786
3787         return JNI_OK;
3788 }
3789
3790
3791 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3792 {
3793         int result;
3794
3795         TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3796
3797         if (vm_created == false)
3798                 return JNI_ERR;
3799
3800         result = jni_attach_current_thread(p_env, thr_args, false);
3801
3802         return result;
3803 }
3804
3805
3806 /* DetachCurrentThread *********************************************************
3807
3808    Detaches the current thread from a Java VM. All Java monitors held
3809    by this thread are released. All Java threads waiting for this
3810    thread to die are notified.
3811
3812    In JDK 1.1, the main thread cannot be detached from the VM. It must
3813    call DestroyJavaVM to unload the entire VM.
3814
3815    In the JDK, the main thread can be detached from the VM.
3816
3817    The main thread, which is the thread that created the Java VM,
3818    cannot be detached from the VM. Instead, the main thread must call
3819    JNI_DestroyJavaVM() to unload the entire VM.
3820
3821 *******************************************************************************/
3822
3823 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3824 {
3825 #if defined(ENABLE_THREADS)
3826         threadobject *t;
3827         bool          result;
3828
3829         TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3830
3831         t = thread_get_current();
3832
3833         /* Sanity check. */
3834
3835         assert(t != NULL);
3836
3837     /* If the given thread has already been detached, this operation
3838            is a no-op. */
3839
3840         result = thread_is_attached(t);
3841
3842         if (result == false)
3843                 return true;
3844
3845         /* We need to pop all frames before we can destroy the table. */
3846
3847         localref_frame_pop_all();
3848
3849         if (!localref_table_destroy())
3850                 return JNI_ERR;
3851
3852         if (!threads_detach_thread(t))
3853                 return JNI_ERR;
3854 #endif
3855
3856         return JNI_OK;
3857 }
3858
3859
3860 /* GetEnv **********************************************************************
3861
3862    If the current thread is not attached to the VM, sets *env to NULL,
3863    and returns JNI_EDETACHED. If the specified version is not
3864    supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3865    sets *env to the appropriate interface, and returns JNI_OK.
3866
3867 *******************************************************************************/
3868
3869 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3870 {
3871         TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
3872
3873         if (vm_created == false) {
3874                 *env = NULL;
3875                 return JNI_EDETACHED;
3876         }
3877
3878 #if defined(ENABLE_THREADS)
3879         if (thread_get_current() == NULL) {
3880                 *env = NULL;
3881
3882                 return JNI_EDETACHED;
3883         }
3884 #endif
3885
3886         /* Check the JNI version. */
3887
3888         if (jni_version_check(version) == true) {
3889                 *env = _Jv_env;
3890                 return JNI_OK;
3891         }
3892
3893 #if defined(ENABLE_JVMTI)
3894         if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
3895                 == JVMTI_VERSION_INTERFACE_JVMTI) {
3896
3897                 *env = (void *) jvmti_new_environment();
3898
3899                 if (env != NULL)
3900                         return JNI_OK;
3901         }
3902 #endif
3903         
3904         *env = NULL;
3905
3906         return JNI_EVERSION;
3907 }
3908
3909
3910 /* AttachCurrentThreadAsDaemon *************************************************
3911
3912    Same semantics as AttachCurrentThread, but the newly-created
3913    java.lang.Thread instance is a daemon.
3914
3915    If the thread has already been attached via either
3916    AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3917    simply sets the value pointed to by penv to the JNIEnv of the
3918    current thread. In this case neither AttachCurrentThread nor this
3919    routine have any effect on the daemon status of the thread.
3920
3921 *******************************************************************************/
3922
3923 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3924 {
3925         int result;
3926
3927         TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
3928
3929         if (vm_created == false)
3930                 return JNI_ERR;
3931
3932         result = jni_attach_current_thread(penv, args, true);
3933
3934         return result;
3935 }
3936
3937
3938 /* JNI invocation table *******************************************************/
3939
3940 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3941         NULL,
3942         NULL,
3943         NULL,
3944
3945         _Jv_JNI_DestroyJavaVM,
3946         _Jv_JNI_AttachCurrentThread,
3947         _Jv_JNI_DetachCurrentThread,
3948         _Jv_JNI_GetEnv,
3949         _Jv_JNI_AttachCurrentThreadAsDaemon
3950 };
3951
3952
3953 /* JNI function table *********************************************************/
3954
3955 struct JNINativeInterface_ _Jv_JNINativeInterface = {
3956         NULL,
3957         NULL,
3958         NULL,
3959         NULL,    
3960         _Jv_JNI_GetVersion,
3961
3962         _Jv_JNI_DefineClass,
3963         jni_FindClass,
3964         _Jv_JNI_FromReflectedMethod,
3965         _Jv_JNI_FromReflectedField,
3966         _Jv_JNI_ToReflectedMethod,
3967         _Jv_JNI_GetSuperclass,
3968         _Jv_JNI_IsAssignableFrom,
3969         _Jv_JNI_ToReflectedField,
3970
3971         _Jv_JNI_Throw,
3972         _Jv_JNI_ThrowNew,
3973         _Jv_JNI_ExceptionOccurred,
3974         jni_ExceptionDescribe,
3975         jni_ExceptionClear,
3976         _Jv_JNI_FatalError,
3977         _Jv_JNI_PushLocalFrame,
3978         _Jv_JNI_PopLocalFrame,
3979
3980         _Jv_JNI_NewGlobalRef,
3981         _Jv_JNI_DeleteGlobalRef,
3982         _Jv_JNI_DeleteLocalRef,
3983         _Jv_JNI_IsSameObject,
3984         _Jv_JNI_NewLocalRef,
3985         _Jv_JNI_EnsureLocalCapacity,
3986
3987         _Jv_JNI_AllocObject,
3988         _Jv_JNI_NewObject,
3989         _Jv_JNI_NewObjectV,
3990         _Jv_JNI_NewObjectA,
3991
3992         _Jv_JNI_GetObjectClass,
3993         _Jv_JNI_IsInstanceOf,
3994
3995         _Jv_JNI_GetMethodID,
3996
3997         _Jv_JNI_CallObjectMethod,
3998         _Jv_JNI_CallObjectMethodV,
3999         _Jv_JNI_CallObjectMethodA,
4000         _Jv_JNI_CallBooleanMethod,
4001         _Jv_JNI_CallBooleanMethodV,
4002         _Jv_JNI_CallBooleanMethodA,
4003         _Jv_JNI_CallByteMethod,
4004         _Jv_JNI_CallByteMethodV,
4005         _Jv_JNI_CallByteMethodA,
4006         _Jv_JNI_CallCharMethod,
4007         _Jv_JNI_CallCharMethodV,
4008         _Jv_JNI_CallCharMethodA,
4009         _Jv_JNI_CallShortMethod,
4010         _Jv_JNI_CallShortMethodV,
4011         _Jv_JNI_CallShortMethodA,
4012         _Jv_JNI_CallIntMethod,
4013         _Jv_JNI_CallIntMethodV,
4014         _Jv_JNI_CallIntMethodA,
4015         _Jv_JNI_CallLongMethod,
4016         _Jv_JNI_CallLongMethodV,
4017         _Jv_JNI_CallLongMethodA,
4018         _Jv_JNI_CallFloatMethod,
4019         _Jv_JNI_CallFloatMethodV,
4020         _Jv_JNI_CallFloatMethodA,
4021         _Jv_JNI_CallDoubleMethod,
4022         _Jv_JNI_CallDoubleMethodV,
4023         _Jv_JNI_CallDoubleMethodA,
4024         _Jv_JNI_CallVoidMethod,
4025         _Jv_JNI_CallVoidMethodV,
4026         _Jv_JNI_CallVoidMethodA,
4027
4028         _Jv_JNI_CallNonvirtualObjectMethod,
4029         _Jv_JNI_CallNonvirtualObjectMethodV,
4030         _Jv_JNI_CallNonvirtualObjectMethodA,
4031         _Jv_JNI_CallNonvirtualBooleanMethod,
4032         _Jv_JNI_CallNonvirtualBooleanMethodV,
4033         _Jv_JNI_CallNonvirtualBooleanMethodA,
4034         _Jv_JNI_CallNonvirtualByteMethod,
4035         _Jv_JNI_CallNonvirtualByteMethodV,
4036         _Jv_JNI_CallNonvirtualByteMethodA,
4037         _Jv_JNI_CallNonvirtualCharMethod,
4038         _Jv_JNI_CallNonvirtualCharMethodV,
4039         _Jv_JNI_CallNonvirtualCharMethodA,
4040         _Jv_JNI_CallNonvirtualShortMethod,
4041         _Jv_JNI_CallNonvirtualShortMethodV,
4042         _Jv_JNI_CallNonvirtualShortMethodA,
4043         _Jv_JNI_CallNonvirtualIntMethod,
4044         _Jv_JNI_CallNonvirtualIntMethodV,
4045         _Jv_JNI_CallNonvirtualIntMethodA,
4046         _Jv_JNI_CallNonvirtualLongMethod,
4047         _Jv_JNI_CallNonvirtualLongMethodV,
4048         _Jv_JNI_CallNonvirtualLongMethodA,
4049         _Jv_JNI_CallNonvirtualFloatMethod,
4050         _Jv_JNI_CallNonvirtualFloatMethodV,
4051         _Jv_JNI_CallNonvirtualFloatMethodA,
4052         _Jv_JNI_CallNonvirtualDoubleMethod,
4053         _Jv_JNI_CallNonvirtualDoubleMethodV,
4054         _Jv_JNI_CallNonvirtualDoubleMethodA,
4055         _Jv_JNI_CallNonvirtualVoidMethod,
4056         _Jv_JNI_CallNonvirtualVoidMethodV,
4057         _Jv_JNI_CallNonvirtualVoidMethodA,
4058
4059         _Jv_JNI_GetFieldID,
4060
4061         _Jv_JNI_GetObjectField,
4062         _Jv_JNI_GetBooleanField,
4063         _Jv_JNI_GetByteField,
4064         _Jv_JNI_GetCharField,
4065         _Jv_JNI_GetShortField,
4066         _Jv_JNI_GetIntField,
4067         _Jv_JNI_GetLongField,
4068         _Jv_JNI_GetFloatField,
4069         _Jv_JNI_GetDoubleField,
4070         _Jv_JNI_SetObjectField,
4071         _Jv_JNI_SetBooleanField,
4072         _Jv_JNI_SetByteField,
4073         _Jv_JNI_SetCharField,
4074         _Jv_JNI_SetShortField,
4075         _Jv_JNI_SetIntField,
4076         _Jv_JNI_SetLongField,
4077         _Jv_JNI_SetFloatField,
4078         _Jv_JNI_SetDoubleField,
4079
4080         _Jv_JNI_GetStaticMethodID,
4081
4082         _Jv_JNI_CallStaticObjectMethod,
4083         _Jv_JNI_CallStaticObjectMethodV,
4084         _Jv_JNI_CallStaticObjectMethodA,
4085         _Jv_JNI_CallStaticBooleanMethod,
4086         _Jv_JNI_CallStaticBooleanMethodV,
4087         _Jv_JNI_CallStaticBooleanMethodA,
4088         _Jv_JNI_CallStaticByteMethod,
4089         _Jv_JNI_CallStaticByteMethodV,
4090         _Jv_JNI_CallStaticByteMethodA,
4091         _Jv_JNI_CallStaticCharMethod,
4092         _Jv_JNI_CallStaticCharMethodV,
4093         _Jv_JNI_CallStaticCharMethodA,
4094         _Jv_JNI_CallStaticShortMethod,
4095         _Jv_JNI_CallStaticShortMethodV,
4096         _Jv_JNI_CallStaticShortMethodA,
4097         _Jv_JNI_CallStaticIntMethod,
4098         _Jv_JNI_CallStaticIntMethodV,
4099         _Jv_JNI_CallStaticIntMethodA,
4100         _Jv_JNI_CallStaticLongMethod,
4101         _Jv_JNI_CallStaticLongMethodV,
4102         _Jv_JNI_CallStaticLongMethodA,
4103         _Jv_JNI_CallStaticFloatMethod,
4104         _Jv_JNI_CallStaticFloatMethodV,
4105         _Jv_JNI_CallStaticFloatMethodA,
4106         _Jv_JNI_CallStaticDoubleMethod,
4107         _Jv_JNI_CallStaticDoubleMethodV,
4108         _Jv_JNI_CallStaticDoubleMethodA,
4109         _Jv_JNI_CallStaticVoidMethod,
4110         _Jv_JNI_CallStaticVoidMethodV,
4111         _Jv_JNI_CallStaticVoidMethodA,
4112
4113         _Jv_JNI_GetStaticFieldID,
4114
4115         _Jv_JNI_GetStaticObjectField,
4116         _Jv_JNI_GetStaticBooleanField,
4117         _Jv_JNI_GetStaticByteField,
4118         _Jv_JNI_GetStaticCharField,
4119         _Jv_JNI_GetStaticShortField,
4120         _Jv_JNI_GetStaticIntField,
4121         _Jv_JNI_GetStaticLongField,
4122         _Jv_JNI_GetStaticFloatField,
4123         _Jv_JNI_GetStaticDoubleField,
4124         _Jv_JNI_SetStaticObjectField,
4125         _Jv_JNI_SetStaticBooleanField,
4126         _Jv_JNI_SetStaticByteField,
4127         _Jv_JNI_SetStaticCharField,
4128         _Jv_JNI_SetStaticShortField,
4129         _Jv_JNI_SetStaticIntField,
4130         _Jv_JNI_SetStaticLongField,
4131         _Jv_JNI_SetStaticFloatField,
4132         _Jv_JNI_SetStaticDoubleField,
4133
4134         _Jv_JNI_NewString,
4135         _Jv_JNI_GetStringLength,
4136         _Jv_JNI_GetStringChars,
4137         _Jv_JNI_ReleaseStringChars,
4138
4139         _Jv_JNI_NewStringUTF,
4140         _Jv_JNI_GetStringUTFLength,
4141         _Jv_JNI_GetStringUTFChars,
4142         _Jv_JNI_ReleaseStringUTFChars,
4143
4144         _Jv_JNI_GetArrayLength,
4145
4146         _Jv_JNI_NewObjectArray,
4147         _Jv_JNI_GetObjectArrayElement,
4148         _Jv_JNI_SetObjectArrayElement,
4149
4150         _Jv_JNI_NewBooleanArray,
4151         _Jv_JNI_NewByteArray,
4152         _Jv_JNI_NewCharArray,
4153         _Jv_JNI_NewShortArray,
4154         _Jv_JNI_NewIntArray,
4155         _Jv_JNI_NewLongArray,
4156         _Jv_JNI_NewFloatArray,
4157         _Jv_JNI_NewDoubleArray,
4158
4159         _Jv_JNI_GetBooleanArrayElements,
4160         _Jv_JNI_GetByteArrayElements,
4161         _Jv_JNI_GetCharArrayElements,
4162         _Jv_JNI_GetShortArrayElements,
4163         _Jv_JNI_GetIntArrayElements,
4164         _Jv_JNI_GetLongArrayElements,
4165         _Jv_JNI_GetFloatArrayElements,
4166         _Jv_JNI_GetDoubleArrayElements,
4167
4168         _Jv_JNI_ReleaseBooleanArrayElements,
4169         _Jv_JNI_ReleaseByteArrayElements,
4170         _Jv_JNI_ReleaseCharArrayElements,
4171         _Jv_JNI_ReleaseShortArrayElements,
4172         _Jv_JNI_ReleaseIntArrayElements,
4173         _Jv_JNI_ReleaseLongArrayElements,
4174         _Jv_JNI_ReleaseFloatArrayElements,
4175         _Jv_JNI_ReleaseDoubleArrayElements,
4176
4177         _Jv_JNI_GetBooleanArrayRegion,
4178         _Jv_JNI_GetByteArrayRegion,
4179         _Jv_JNI_GetCharArrayRegion,
4180         _Jv_JNI_GetShortArrayRegion,
4181         _Jv_JNI_GetIntArrayRegion,
4182         _Jv_JNI_GetLongArrayRegion,
4183         _Jv_JNI_GetFloatArrayRegion,
4184         _Jv_JNI_GetDoubleArrayRegion,
4185         _Jv_JNI_SetBooleanArrayRegion,
4186         _Jv_JNI_SetByteArrayRegion,
4187         _Jv_JNI_SetCharArrayRegion,
4188         _Jv_JNI_SetShortArrayRegion,
4189         _Jv_JNI_SetIntArrayRegion,
4190         _Jv_JNI_SetLongArrayRegion,
4191         _Jv_JNI_SetFloatArrayRegion,
4192         _Jv_JNI_SetDoubleArrayRegion,
4193
4194         _Jv_JNI_RegisterNatives,
4195         _Jv_JNI_UnregisterNatives,
4196
4197         _Jv_JNI_MonitorEnter,
4198         _Jv_JNI_MonitorExit,
4199
4200         _Jv_JNI_GetJavaVM,
4201
4202         /* New JNI 1.2 functions. */
4203
4204         _Jv_JNI_GetStringRegion,
4205         _Jv_JNI_GetStringUTFRegion,
4206
4207         _Jv_JNI_GetPrimitiveArrayCritical,
4208         _Jv_JNI_ReleasePrimitiveArrayCritical,
4209
4210         _Jv_JNI_GetStringCritical,
4211         _Jv_JNI_ReleaseStringCritical,
4212
4213         _Jv_JNI_NewWeakGlobalRef,
4214         _Jv_JNI_DeleteWeakGlobalRef,
4215
4216         _Jv_JNI_ExceptionCheck,
4217
4218         /* New JNI 1.4 functions. */
4219
4220         _Jv_JNI_NewDirectByteBuffer,
4221         _Jv_JNI_GetDirectBufferAddress,
4222         _Jv_JNI_GetDirectBufferCapacity,
4223
4224         /* New JNI 1.6 functions. */
4225
4226         jni_GetObjectRefType
4227 };
4228
4229
4230 /* Invocation API Functions ***************************************************/
4231
4232 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4233
4234    Returns a default configuration for the Java VM.
4235
4236 *******************************************************************************/
4237
4238 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4239 {
4240         JavaVMInitArgs *_vm_args;
4241
4242         _vm_args = (JavaVMInitArgs *) vm_args;
4243
4244         /* GNU classpath currently supports JNI 1.2 */
4245
4246         switch (_vm_args->version) {
4247     case JNI_VERSION_1_1:
4248                 _vm_args->version = JNI_VERSION_1_1;
4249                 break;
4250
4251     case JNI_VERSION_1_2:
4252     case JNI_VERSION_1_4:
4253                 _vm_args->ignoreUnrecognized = JNI_FALSE;
4254                 _vm_args->options = NULL;
4255                 _vm_args->nOptions = 0;
4256                 break;
4257
4258     default:
4259                 return -1;
4260         }
4261   
4262         return 0;
4263 }
4264
4265
4266 /* JNI_GetCreatedJavaVMs *******************************************************
4267
4268    Returns all Java VMs that have been created. Pointers to VMs are written in
4269    the buffer vmBuf in the order they are created. At most bufLen number of
4270    entries will be written. The total number of created VMs is returned in
4271    *nVMs.
4272
4273 *******************************************************************************/
4274
4275 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4276 {
4277         TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4278
4279         if (bufLen <= 0)
4280                 return JNI_ERR;
4281
4282         /* We currently only support 1 VM running. */
4283
4284         vmBuf[0] = (JavaVM *) _Jv_jvm;
4285         *nVMs    = 1;
4286
4287     return JNI_OK;
4288 }
4289
4290
4291 /* JNI_CreateJavaVM ************************************************************
4292
4293    Loads and initializes a Java VM. The current thread becomes the main thread.
4294    Sets the env argument to the JNI interface pointer of the main thread.
4295
4296 *******************************************************************************/
4297
4298 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4299 {
4300         TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4301
4302         /* actually create the JVM */
4303
4304         if (!vm_createjvm(p_vm, p_env, vm_args))
4305                 return JNI_ERR;
4306
4307         return JNI_OK;
4308 }
4309
4310
4311 /*
4312  * These are local overrides for various environment variables in Emacs.
4313  * Please do not remove this and leave it at the end of the file, where
4314  * Emacs will automagically detect them.
4315  * ---------------------------------------------------------------------
4316  * Local variables:
4317  * mode: c
4318  * indent-tabs-mode: t
4319  * c-basic-offset: 4
4320  * tab-width: 4
4321  * End:
4322  * vim:noexpandtab:sw=4:ts=4:
4323  */