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