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