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