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