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