1 /* src/native/jni.c - implementation of the Java Native Interface functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
34 #include "mm/gc-common.h"
35 #include "mm/memory.h"
37 #include "native/jni.h"
38 #include "native/llni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
42 #if defined(ENABLE_JAVASE)
43 # if defined(WITH_CLASSPATH_GNU)
44 # include "native/include/gnu_classpath_Pointer.h"
46 # if SIZEOF_VOID_P == 8
47 # include "native/include/gnu_classpath_Pointer64.h"
49 # include "native/include/gnu_classpath_Pointer32.h"
54 #include "native/include/java_lang_Object.h"
55 #include "native/include/java_lang_String.h"
56 #include "native/include/java_lang_Throwable.h"
58 #if defined(ENABLE_JAVASE)
59 # if defined(WITH_CLASSPATH_SUN)
60 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
63 /* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
64 we pre-define it here to prevent a compiler warning for Sun
67 struct java_lang_ClassLoader;
69 # include "native/include/java_lang_Class.h"
70 # include "native/include/java_lang_ClassLoader.h"
72 # include "native/include/java_lang_reflect_Constructor.h"
73 # include "native/include/java_lang_reflect_Field.h"
74 # include "native/include/java_lang_reflect_Method.h"
76 # include "native/include/java_nio_Buffer.h"
78 # if defined(WITH_CLASSPATH_GNU)
79 # include "native/include/java_lang_reflect_VMConstructor.h"
80 # include "native/include/java_lang_reflect_VMField.h"
81 # include "native/include/java_lang_reflect_VMMethod.h"
83 # include "native/include/java_nio_DirectByteBufferImpl.h"
87 #if defined(ENABLE_JVMTI)
88 # include "native/jvmti/cacaodbg.h"
91 #include "native/vm/java_lang_Class.h"
93 #if defined(ENABLE_JAVASE)
94 # include "native/vm/reflect.h"
97 #include "threads/lock-common.h"
98 #include "threads/thread.h"
100 #include "toolbox/logging.h"
102 #include "vm/array.h"
103 #include "vm/builtin.h"
104 #include "vm/exceptions.h"
105 #include "vm/global.h"
106 #include "vm/initialize.h"
107 #include "vm/primitive.h"
108 #include "vm/resolve.h"
109 #include "vm/stringlocal.h"
112 #include "vm/jit/argument.h"
113 #include "vm/jit/asmpart.h"
114 #include "vm/jit/jit.h"
115 #include "vm/jit/stacktrace.h"
117 #include "vmcore/loader.h"
118 #include "vmcore/options.h"
119 #include "vmcore/statistics.h"
122 /* debug **********************************************************************/
125 # define TRACEJNICALLS(text) \
127 if (opt_TraceJNICalls) { \
132 # define TRACEJNICALLS(text)
136 /* global variables ***********************************************************/
138 /* global reference table *****************************************************/
140 /* hashsize must be power of 2 */
142 #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
144 static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
147 /* direct buffer stuff ********************************************************/
149 #if defined(ENABLE_JAVASE)
150 static classinfo *class_java_nio_Buffer;
152 # if defined(WITH_CLASSPATH_GNU)
154 static classinfo *class_java_nio_DirectByteBufferImpl;
155 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
157 # if SIZEOF_VOID_P == 8
158 static classinfo *class_gnu_classpath_Pointer64;
160 static classinfo *class_gnu_classpath_Pointer32;
163 static methodinfo *dbbirw_init;
165 # elif defined(WITH_CLASSPATH_SUN)
167 static classinfo *class_sun_nio_ch_DirectBuffer;
168 static classinfo *class_java_nio_DirectByteBuffer;
170 static methodinfo *dbb_init;
176 /* some forward declarations **************************************************/
178 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
181 /* jni_init ********************************************************************
183 Initialize the JNI subsystem.
185 *******************************************************************************/
189 TRACESUBSYSTEMINITIALIZATION("jni_init");
191 /* create global ref hashtable */
193 hashtable_global_ref = NEW(hashtable);
195 hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
198 #if defined(ENABLE_JAVASE)
199 /* Direct buffer stuff. */
201 if (!(class_java_nio_Buffer =
202 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
203 !link_class(class_java_nio_Buffer))
206 # if defined(WITH_CLASSPATH_GNU)
208 if (!(class_java_nio_DirectByteBufferImpl =
209 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
210 !link_class(class_java_nio_DirectByteBufferImpl))
213 if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
214 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
215 !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
219 class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
221 utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
224 # if SIZEOF_VOID_P == 8
225 if (!(class_gnu_classpath_Pointer64 =
226 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
227 !link_class(class_gnu_classpath_Pointer64))
230 if (!(class_gnu_classpath_Pointer32 =
231 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
232 !link_class(class_gnu_classpath_Pointer32))
236 # elif defined(WITH_CLASSPATH_SUN)
238 if (!(class_sun_nio_ch_DirectBuffer =
239 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
240 vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
242 if (!link_class(class_sun_nio_ch_DirectBuffer))
243 vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
245 if (!(class_java_nio_DirectByteBuffer =
246 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
247 vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
249 if (!link_class(class_java_nio_DirectByteBuffer))
250 vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
253 class_resolvemethod(class_java_nio_DirectByteBuffer,
255 utf_new_char("(JI)V"))))
256 vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
260 #endif /* defined(ENABLE_JAVASE) */
266 /* jni_version_check ***********************************************************
268 Check if the given JNI version is supported.
271 version....JNI version to check
275 false......not supported
277 *******************************************************************************/
279 bool jni_version_check(int version)
282 case JNI_VERSION_1_1:
283 case JNI_VERSION_1_2:
284 case JNI_VERSION_1_4:
285 case JNI_VERSION_1_6:
293 /* _Jv_jni_CallObjectMethod ****************************************************
295 Internal function to call Java Object methods.
297 *******************************************************************************/
299 static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
301 methodinfo *m, va_list ap)
306 STATISTICS(jniinvokation());
309 exceptions_throw_nullpointerexception();
313 /* Class initialization is done by the JIT compiler. This is ok
314 since a static method always belongs to the declaring class. */
316 if (m->flags & ACC_STATIC) {
317 /* For static methods we reset the object. */
322 /* for convenience */
327 /* For instance methods we make a virtual function table lookup. */
329 resm = method_vftbl_lookup(vftbl, m);
332 STATISTICS(jnicallXmethodnvokation());
334 ro = vm_call_method_valist(resm, o, ap);
340 /* _Jv_jni_CallObjectMethodA ***************************************************
342 Internal function to call Java Object methods.
344 *******************************************************************************/
346 static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
354 STATISTICS(jniinvokation());
357 exceptions_throw_nullpointerexception();
361 /* Class initialization is done by the JIT compiler. This is ok
362 since a static method always belongs to the declaring class. */
364 if (m->flags & ACC_STATIC) {
365 /* For static methods we reset the object. */
370 /* for convenience */
375 /* For instance methods we make a virtual function table lookup. */
377 resm = method_vftbl_lookup(vftbl, m);
380 STATISTICS(jnicallXmethodnvokation());
382 ro = vm_call_method_jvalue(resm, o, args);
388 /* _Jv_jni_CallIntMethod *******************************************************
390 Internal function to call Java integer class methods (boolean,
391 byte, char, short, int).
393 *******************************************************************************/
395 static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
396 methodinfo *m, va_list ap)
401 STATISTICS(jniinvokation());
404 exceptions_throw_nullpointerexception();
408 /* Class initialization is done by the JIT compiler. This is ok
409 since a static method always belongs to the declaring class. */
411 if (m->flags & ACC_STATIC) {
412 /* For static methods we reset the object. */
417 /* for convenience */
422 /* For instance methods we make a virtual function table lookup. */
424 resm = method_vftbl_lookup(vftbl, m);
427 STATISTICS(jnicallXmethodnvokation());
429 i = vm_call_method_int_valist(resm, o, ap);
435 /* _Jv_jni_CallIntMethodA ******************************************************
437 Internal function to call Java integer class methods (boolean,
438 byte, char, short, int).
440 *******************************************************************************/
442 static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
443 methodinfo *m, const jvalue *args)
448 STATISTICS(jniinvokation());
451 exceptions_throw_nullpointerexception();
455 /* Class initialization is done by the JIT compiler. This is ok
456 since a static method always belongs to the declaring class. */
458 if (m->flags & ACC_STATIC) {
459 /* For static methods we reset the object. */
464 /* for convenience */
469 /* For instance methods we make a virtual function table lookup. */
471 resm = method_vftbl_lookup(vftbl, m);
474 STATISTICS(jnicallXmethodnvokation());
476 i = vm_call_method_int_jvalue(resm, o, args);
482 /* _Jv_jni_CallLongMethod ******************************************************
484 Internal function to call Java long methods.
486 *******************************************************************************/
488 static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
489 methodinfo *m, va_list ap)
494 STATISTICS(jniinvokation());
497 exceptions_throw_nullpointerexception();
501 /* Class initialization is done by the JIT compiler. This is ok
502 since a static method always belongs to the declaring class. */
504 if (m->flags & ACC_STATIC) {
505 /* For static methods we reset the object. */
510 /* for convenience */
515 /* For instance methods we make a virtual function table lookup. */
517 resm = method_vftbl_lookup(vftbl, m);
520 STATISTICS(jnicallXmethodnvokation());
522 l = vm_call_method_long_valist(resm, o, ap);
528 /* _Jv_jni_CallLongMethodA *****************************************************
530 Internal function to call Java long methods.
532 *******************************************************************************/
534 static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
535 methodinfo *m, const jvalue *args)
540 STATISTICS(jniinvokation());
543 exceptions_throw_nullpointerexception();
547 /* Class initialization is done by the JIT compiler. This is ok
548 since a static method always belongs to the declaring class. */
550 if (m->flags & ACC_STATIC) {
551 /* For static methods we reset the object. */
556 /* for convenience */
561 /* For instance methods we make a virtual function table lookup. */
563 resm = method_vftbl_lookup(vftbl, m);
566 STATISTICS(jnicallXmethodnvokation());
568 l = vm_call_method_long_jvalue(resm, o, args);
574 /* _Jv_jni_CallFloatMethod *****************************************************
576 Internal function to call Java float methods.
578 *******************************************************************************/
580 static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
581 methodinfo *m, va_list ap)
586 /* Class initialization is done by the JIT compiler. This is ok
587 since a static method always belongs to the declaring class. */
589 if (m->flags & ACC_STATIC) {
590 /* For static methods we reset the object. */
595 /* for convenience */
600 /* For instance methods we make a virtual function table lookup. */
602 resm = method_vftbl_lookup(vftbl, m);
605 STATISTICS(jnicallXmethodnvokation());
607 f = vm_call_method_float_valist(resm, o, ap);
613 /* _Jv_jni_CallFloatMethodA ****************************************************
615 Internal function to call Java float methods.
617 *******************************************************************************/
619 static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
620 methodinfo *m, const jvalue *args)
625 /* Class initialization is done by the JIT compiler. This is ok
626 since a static method always belongs to the declaring class. */
628 if (m->flags & ACC_STATIC) {
629 /* For static methods we reset the object. */
634 /* for convenience */
639 /* For instance methods we make a virtual function table lookup. */
641 resm = method_vftbl_lookup(vftbl, m);
644 STATISTICS(jnicallXmethodnvokation());
646 f = vm_call_method_float_jvalue(resm, o, args);
652 /* _Jv_jni_CallDoubleMethod ****************************************************
654 Internal function to call Java double methods.
656 *******************************************************************************/
658 static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
659 methodinfo *m, va_list ap)
664 /* Class initialization is done by the JIT compiler. This is ok
665 since a static method always belongs to the declaring class. */
667 if (m->flags & ACC_STATIC) {
668 /* For static methods we reset the object. */
673 /* for convenience */
678 /* For instance methods we make a virtual function table lookup. */
680 resm = method_vftbl_lookup(vftbl, m);
683 d = vm_call_method_double_valist(resm, o, ap);
689 /* _Jv_jni_CallDoubleMethodA ***************************************************
691 Internal function to call Java double methods.
693 *******************************************************************************/
695 static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
696 methodinfo *m, const jvalue *args)
701 /* Class initialization is done by the JIT compiler. This is ok
702 since a static method always belongs to the declaring class. */
704 if (m->flags & ACC_STATIC) {
705 /* For static methods we reset the object. */
710 /* for convenience */
715 /* For instance methods we make a virtual function table lookup. */
717 resm = method_vftbl_lookup(vftbl, m);
720 d = vm_call_method_double_jvalue(resm, o, args);
726 /* _Jv_jni_CallVoidMethod ******************************************************
728 Internal function to call Java void methods.
730 *******************************************************************************/
732 static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
733 methodinfo *m, va_list ap)
738 exceptions_throw_nullpointerexception();
742 /* Class initialization is done by the JIT compiler. This is ok
743 since a static method always belongs to the declaring class. */
745 if (m->flags & ACC_STATIC) {
746 /* For static methods we reset the object. */
751 /* for convenience */
756 /* For instance methods we make a virtual function table lookup. */
758 resm = method_vftbl_lookup(vftbl, m);
761 STATISTICS(jnicallXmethodnvokation());
763 (void) vm_call_method_valist(resm, o, ap);
767 /* _Jv_jni_CallVoidMethodA *****************************************************
769 Internal function to call Java void methods.
771 *******************************************************************************/
773 static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
774 methodinfo *m, const jvalue *args)
779 exceptions_throw_nullpointerexception();
783 /* Class initialization is done by the JIT compiler. This is ok
784 since a static method always belongs to the declaring class. */
786 if (m->flags & ACC_STATIC) {
787 /* For static methods we reset the object. */
792 /* for convenience */
797 /* For instance methods we make a virtual function table lookup. */
799 resm = method_vftbl_lookup(vftbl, m);
802 STATISTICS(jnicallXmethodnvokation());
804 (void) vm_call_method_jvalue(resm, o, args);
808 /* GetVersion ******************************************************************
810 Returns the major version number in the higher 16 bits and the
811 minor version number in the lower 16 bits.
813 *******************************************************************************/
815 jint _Jv_JNI_GetVersion(JNIEnv *env)
817 TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
819 /* We support JNI 1.6. */
821 return JNI_VERSION_1_6;
825 /* Class Operations ***********************************************************/
827 /* DefineClass *****************************************************************
829 Loads a class from a buffer of raw class data. The buffer
830 containing the raw class data is not referenced by the VM after the
831 DefineClass call returns, and it may be discarded if desired.
833 *******************************************************************************/
835 jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
836 const jbyte *buf, jsize bufLen)
838 #if defined(ENABLE_JAVASE)
844 TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
846 u = utf_new_char(name);
847 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
849 c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
851 co = LLNI_classinfo_wrap(c);
853 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
855 vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
857 /* keep compiler happy */
864 /* FindClass *******************************************************************
866 This function loads a locally-defined class. It searches the
867 directories and zip files specified by the CLASSPATH environment
868 variable for the class with the specified name.
870 *******************************************************************************/
872 jclass jni_FindClass(JNIEnv *env, const char *name)
874 #if defined(ENABLE_JAVASE)
881 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
883 /* FIXME If name is NULL we have a problem here. */
885 u = utf_new_char_classname((char *) name);
887 if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
888 exceptions_throw_noclassdeffounderror(u);
892 /* Check stacktrace for classloader, if one found use it,
893 otherwise use the system classloader. */
895 /* Quote from the JNI documentation:
897 In the Java 2 Platform, FindClass locates the class loader
898 associated with the current native method. If the native code
899 belongs to a system class, no class loader will be
900 involved. Otherwise, the proper class loader will be invoked to
901 load and link the named class. When FindClass is called through
902 the Invocation Interface, there is no current native method or
903 its associated class loader. In that case, the result of
904 ClassLoader.getBaseClassLoader is used." */
906 cc = stacktrace_get_current_class();
909 c = load_class_from_sysloader(u);
911 c = load_class_from_classloader(u, cc->classloader);
914 resolve_handle_pending_exception(true);
921 co = LLNI_classinfo_wrap(c);
923 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
925 #elif defined(ENABLE_JAVAME_CLDC1_1)
930 TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
932 u = utf_new_char_classname((char *) name);
933 c = load_class_bootstrap(u);
936 resolve_handle_pending_exception(true);
943 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
946 vm_abort("jni_FindClass: not implemented in this configuration");
948 /* keep compiler happy */
955 /* GetSuperclass ***************************************************************
957 If clazz represents any class other than the class Object, then
958 this function returns the object that represents the superclass of
959 the class specified by clazz.
961 *******************************************************************************/
963 jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
969 TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
971 c = LLNI_classinfo_unwrap(sub);
976 super = class_get_superclass(c);
978 co = LLNI_classinfo_wrap(super);
980 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
984 /* IsAssignableFrom ************************************************************
986 Determines whether an object of sub can be safely cast to sup.
988 *******************************************************************************/
990 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
992 java_lang_Class *csup;
993 java_lang_Class *csub;
995 csup = (java_lang_Class *) sup;
996 csub = (java_lang_Class *) sub;
998 STATISTICS(jniinvokation());
1000 return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
1004 /* Throw ***********************************************************************
1006 Causes a java.lang.Throwable object to be thrown.
1008 *******************************************************************************/
1010 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1014 STATISTICS(jniinvokation());
1016 o = (java_handle_t *) obj;
1018 exceptions_set_exception(o);
1024 /* ThrowNew ********************************************************************
1026 Constructs an exception object from the specified class with the
1027 message specified by message and causes that exception to be
1030 *******************************************************************************/
1032 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1038 STATISTICS(jniinvokation());
1040 c = LLNI_classinfo_unwrap(clazz);
1043 s = javastring_new_from_utf_string(msg);
1045 /* instantiate exception object */
1047 o = native_new_and_init_string(c, s);
1052 exceptions_set_exception(o);
1058 /* ExceptionOccurred ***********************************************************
1060 Determines if an exception is being thrown. The exception stays
1061 being thrown until either the native code calls ExceptionClear(),
1062 or the Java code handles the exception.
1064 *******************************************************************************/
1066 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1070 TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1072 o = exceptions_get_exception();
1074 return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
1078 /* ExceptionDescribe ***********************************************************
1080 Prints an exception and a backtrace of the stack to a system
1081 error-reporting channel, such as stderr. This is a convenience
1082 routine provided for debugging.
1084 *******************************************************************************/
1086 void jni_ExceptionDescribe(JNIEnv *env)
1088 TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1090 exceptions_print_stacktrace();
1094 /* ExceptionClear **************************************************************
1096 Clears any exception that is currently being thrown. If no
1097 exception is currently being thrown, this routine has no effect.
1099 *******************************************************************************/
1101 void jni_ExceptionClear(JNIEnv *env)
1103 TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1105 exceptions_clear_exception();
1109 /* FatalError ******************************************************************
1111 Raises a fatal error and does not expect the VM to recover. This
1112 function does not return.
1114 *******************************************************************************/
1116 void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1118 STATISTICS(jniinvokation());
1120 /* this seems to be the best way */
1122 vm_abort("JNI Fatal error: %s", msg);
1126 /* PushLocalFrame **************************************************************
1128 Creates a new local reference frame, in which at least a given
1129 number of local references can be created.
1131 *******************************************************************************/
1133 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
1135 STATISTICS(jniinvokation());
1140 /* add new local reference frame to current table */
1142 if (!localref_frame_push(capacity))
1149 /* PopLocalFrame ***************************************************************
1151 Pops off the current local reference frame, frees all the local
1152 references, and returns a local reference in the previous local
1153 reference frame for the given result object.
1155 *******************************************************************************/
1157 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
1159 STATISTICS(jniinvokation());
1161 /* release all current local frames */
1163 localref_frame_pop_all();
1165 /* add local reference and return the value */
1167 return _Jv_JNI_NewLocalRef(env, result);
1171 /* DeleteLocalRef **************************************************************
1173 Deletes the local reference pointed to by localRef.
1175 *******************************************************************************/
1177 void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
1181 STATISTICS(jniinvokation());
1183 o = (java_handle_t *) localRef;
1188 /* delete the reference */
1194 /* IsSameObject ****************************************************************
1196 Tests whether two references refer to the same Java object.
1198 *******************************************************************************/
1200 jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1206 STATISTICS(jniinvokation());
1208 o1 = (java_handle_t *) ref1;
1209 o2 = (java_handle_t *) ref2;
1211 LLNI_CRITICAL_START;
1213 if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1224 /* NewLocalRef *****************************************************************
1226 Creates a new local reference that refers to the same object as ref.
1228 *******************************************************************************/
1230 jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
1233 java_handle_t *localref;
1235 STATISTICS(jniinvokation());
1237 o = (java_handle_t *) ref;
1242 /* insert the reference */
1244 localref = localref_add(LLNI_DIRECT(o));
1246 return (jobject) localref;
1250 /* EnsureLocalCapacity *********************************************************
1252 Ensures that at least a given number of local references can be
1253 created in the current thread
1255 *******************************************************************************/
1257 jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1259 localref_table *lrt;
1261 STATISTICS(jniinvokation());
1263 /* get local reference table (thread specific) */
1265 lrt = LOCALREFTABLE;
1267 /* check if capacity elements are available in the local references table */
1269 if ((lrt->used + capacity) > lrt->capacity)
1270 return _Jv_JNI_PushLocalFrame(env, capacity);
1276 /* AllocObject *****************************************************************
1278 Allocates a new Java object without invoking any of the
1279 constructors for the object. Returns a reference to the object.
1281 *******************************************************************************/
1283 jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1288 STATISTICS(jniinvokation());
1290 c = LLNI_classinfo_unwrap(clazz);
1292 if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1293 exceptions_throw_instantiationexception(c);
1299 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1303 /* NewObject *******************************************************************
1305 Programmers place all arguments that are to be passed to the
1306 constructor immediately following the methodID
1307 argument. NewObject() accepts these arguments and passes them to
1308 the Java method that the programmer wishes to invoke.
1310 *******************************************************************************/
1312 jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1319 STATISTICS(jniinvokation());
1321 c = LLNI_classinfo_unwrap(clazz);
1322 m = (methodinfo *) methodID;
1331 /* call constructor */
1333 va_start(ap, methodID);
1334 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1337 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1341 /* NewObjectV ******************************************************************
1343 Programmers place all arguments that are to be passed to the
1344 constructor in an args argument of type va_list that immediately
1345 follows the methodID argument. NewObjectV() accepts these
1346 arguments, and, in turn, passes them to the Java method that the
1347 programmer wishes to invoke.
1349 *******************************************************************************/
1351 jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1358 STATISTICS(jniinvokation());
1360 c = LLNI_classinfo_unwrap(clazz);
1361 m = (methodinfo *) methodID;
1370 /* call constructor */
1372 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1374 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1378 /* NewObjectA *****************************************************************
1380 Programmers place all arguments that are to be passed to the
1381 constructor in an args array of jvalues that immediately follows
1382 the methodID argument. NewObjectA() accepts the arguments in this
1383 array, and, in turn, passes them to the Java method that the
1384 programmer wishes to invoke.
1386 *******************************************************************************/
1388 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1395 STATISTICS(jniinvokation());
1397 c = LLNI_classinfo_unwrap(clazz);
1398 m = (methodinfo *) methodID;
1407 /* call constructor */
1409 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1411 return _Jv_JNI_NewLocalRef(env, (jobject) o);
1415 /* GetObjectClass **************************************************************
1417 Returns the class of an object.
1419 *******************************************************************************/
1421 jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
1425 java_lang_Class *co;
1427 STATISTICS(jniinvokation());
1429 o = (java_handle_t *) obj;
1431 if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
1434 LLNI_class_get(o, c);
1436 co = LLNI_classinfo_wrap(c);
1438 return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
1442 /* IsInstanceOf ****************************************************************
1444 Tests whether an object is an instance of a class.
1446 *******************************************************************************/
1448 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1451 java_lang_Object *o;
1453 STATISTICS(jniinvokation());
1455 c = (java_lang_Class *) clazz;
1456 o = (java_lang_Object *) obj;
1458 return _Jv_java_lang_Class_isInstance(c, o);
1462 /* Reflection Support *********************************************************/
1464 /* FromReflectedMethod *********************************************************
1466 Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1467 object to a method ID.
1469 *******************************************************************************/
1471 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1473 #if defined(ENABLE_JAVASE)
1475 java_lang_reflect_Method *rm;
1476 java_lang_reflect_Constructor *rc;
1481 #if defined(WITH_CLASSPATH_GNU)
1482 java_lang_reflect_VMMethod *rvmm;
1483 java_lang_reflect_VMConstructor *rvmc;
1486 TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1488 o = (java_handle_t *) method;
1493 if (o->vftbl->class == class_java_lang_reflect_Constructor) {
1494 rc = (java_lang_reflect_Constructor *) method;
1496 #if defined(WITH_CLASSPATH_GNU)
1498 LLNI_field_get_ref(rc, cons , rvmc);
1499 LLNI_field_get_cls(rvmc, clazz, c);
1500 LLNI_field_get_val(rvmc, slot , slot);
1502 #elif defined(WITH_CLASSPATH_SUN)
1504 LLNI_field_get_cls(rc, clazz, c);
1505 LLNI_field_get_val(rc, slot , slot);
1508 # error unknown configuration
1512 assert(o->vftbl->class == class_java_lang_reflect_Method);
1514 rm = (java_lang_reflect_Method *) method;
1516 #if defined(WITH_CLASSPATH_GNU)
1518 LLNI_field_get_ref(rm, m , rvmm);
1519 LLNI_field_get_cls(rvmm, clazz, c);
1520 LLNI_field_get_val(rvmm, slot , slot);
1522 #elif defined(WITH_CLASSPATH_SUN)
1524 LLNI_field_get_cls(rm, clazz, c);
1525 LLNI_field_get_val(rm, slot , slot);
1528 # error unknown configuration
1532 m = &(c->methods[slot]);
1534 return (jmethodID) m;
1536 vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1538 /* Keep compiler happy. */
1545 /* FromReflectedField **********************************************************
1547 Converts a java.lang.reflect.Field to a field ID.
1549 *******************************************************************************/
1551 jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1553 #if defined(ENABLE_JAVASE)
1554 java_lang_reflect_Field *rf;
1559 #if defined(WITH_CLASSPATH_GNU)
1560 java_lang_reflect_VMField *rvmf;
1563 TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1565 rf = (java_lang_reflect_Field *) field;
1570 #if defined(WITH_CLASSPATH_GNU)
1572 LLNI_field_get_ref(rf, f, rvmf);
1573 LLNI_field_get_cls(rvmf, clazz, c);
1574 LLNI_field_get_val(rvmf, slot , slot);
1576 #elif defined(WITH_CLASSPATH_SUN)
1578 LLNI_field_get_cls(rf, clazz, c);
1579 LLNI_field_get_val(rf, slot , slot);
1582 # error unknown configuration
1585 f = &(c->fields[slot]);
1587 return (jfieldID) f;
1589 vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1591 /* Keep compiler happy. */
1598 /* ToReflectedMethod ***********************************************************
1600 Converts a method ID derived from cls to an instance of the
1601 java.lang.reflect.Method class or to an instance of the
1602 java.lang.reflect.Constructor class.
1604 *******************************************************************************/
1606 jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
1609 #if defined(ENABLE_JAVASE)
1611 java_lang_reflect_Constructor *rc;
1612 java_lang_reflect_Method *rm;
1614 TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1616 m = (methodinfo *) methodID;
1618 /* HotSpot does the same assert. */
1620 assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1622 if (m->name == utf_init) {
1623 rc = reflect_constructor_new(m);
1625 return (jobject) rc;
1628 rm = reflect_method_new(m);
1630 return (jobject) rm;
1633 vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
1635 /* keep compiler happy */
1642 /* ToReflectedField ************************************************************
1644 Converts a field ID derived from cls to an instance of the
1645 java.lang.reflect.Field class.
1647 *******************************************************************************/
1649 jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1652 STATISTICS(jniinvokation());
1654 log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1660 /* Calling Instance Methods ***************************************************/
1662 /* GetMethodID *****************************************************************
1664 Returns the method ID for an instance (nonstatic) method of a class
1665 or interface. The method may be defined in one of the clazz's
1666 superclasses and inherited by clazz. The method is determined by
1667 its name and signature.
1669 GetMethodID() causes an uninitialized class to be initialized.
1671 *******************************************************************************/
1673 jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1681 STATISTICS(jniinvokation());
1683 c = LLNI_classinfo_unwrap(clazz);
1688 if (!(c->state & CLASS_INITIALIZED))
1689 if (!initialize_class(c))
1692 /* try to get the method of the class or one of it's superclasses */
1694 uname = utf_new_char((char *) name);
1695 udesc = utf_new_char((char *) sig);
1697 m = class_resolvemethod(c, uname, udesc);
1699 if ((m == NULL) || (m->flags & ACC_STATIC)) {
1700 exceptions_throw_nosuchmethoderror(c, uname, udesc);
1705 return (jmethodID) m;
1709 /* JNI-functions for calling instance methods *********************************/
1711 #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1712 type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1713 jmethodID methodID, ...) \
1720 o = (java_handle_t *) obj; \
1721 m = (methodinfo *) methodID; \
1723 va_start(ap, methodID); \
1724 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1730 JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1731 JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1732 JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1733 JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1734 JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1735 JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1736 JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1737 JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1740 #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1741 type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1742 jmethodID methodID, va_list args) \
1748 o = (java_handle_t *) obj; \
1749 m = (methodinfo *) methodID; \
1751 ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1756 JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1757 JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1758 JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1759 JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1760 JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1761 JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1762 JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1763 JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1766 #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1767 type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1768 jmethodID methodID, \
1769 const jvalue *args) \
1775 o = (java_handle_t *) obj; \
1776 m = (methodinfo *) methodID; \
1778 ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1783 JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1784 JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1785 JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1786 JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1787 JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1788 JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1789 JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1790 JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1793 jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1801 o = (java_handle_t *) obj;
1802 m = (methodinfo *) methodID;
1804 va_start(ap, methodID);
1805 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1808 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1812 jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1819 o = (java_handle_t *) obj;
1820 m = (methodinfo *) methodID;
1822 ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1824 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1828 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1835 o = (java_handle_t *) obj;
1836 m = (methodinfo *) methodID;
1838 ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1840 return _Jv_JNI_NewLocalRef(env, (jobject) ret);
1845 void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1851 o = (java_handle_t *) obj;
1852 m = (methodinfo *) methodID;
1854 va_start(ap, methodID);
1855 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1860 void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1866 o = (java_handle_t *) obj;
1867 m = (methodinfo *) methodID;
1869 _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1873 void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1879 o = (java_handle_t *) obj;
1880 m = (methodinfo *) methodID;
1882 _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1887 #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1888 type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1889 jclass clazz, jmethodID methodID, \
1898 o = (java_handle_t *) obj; \
1899 c = LLNI_classinfo_unwrap(clazz); \
1900 m = (methodinfo *) methodID; \
1902 va_start(ap, methodID); \
1903 ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1909 JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1910 JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1911 JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1912 JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1913 JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1914 JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1915 JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1916 JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1919 #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1920 type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1921 jclass clazz, jmethodID methodID, \
1929 o = (java_handle_t *) obj; \
1930 c = LLNI_classinfo_unwrap(clazz); \
1931 m = (methodinfo *) methodID; \
1933 ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1938 JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1939 JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1940 JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1941 JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1942 JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1943 JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1944 JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1945 JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1948 #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1949 type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1950 jclass clazz, jmethodID methodID, \
1951 const jvalue *args) \
1953 log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1958 JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1959 JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1960 JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1961 JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1962 JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1963 JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1964 JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1965 JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1967 jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1968 jclass clazz, jmethodID methodID,
1977 o = (java_handle_t *) obj;
1978 c = LLNI_classinfo_unwrap(clazz);
1979 m = (methodinfo *) methodID;
1981 va_start(ap, methodID);
1982 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1985 return _Jv_JNI_NewLocalRef(env, (jobject) r);
1989 jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1990 jclass clazz, jmethodID methodID,
1998 o = (java_handle_t *) obj;
1999 c = LLNI_classinfo_unwrap(clazz);
2000 m = (methodinfo *) methodID;
2002 r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
2004 return _Jv_JNI_NewLocalRef(env, (jobject) r);
2008 jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
2009 jclass clazz, jmethodID methodID,
2012 log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
2014 return _Jv_JNI_NewLocalRef(env, NULL);
2018 void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
2019 jmethodID methodID, ...)
2026 o = (java_handle_t *) obj;
2027 c = LLNI_classinfo_unwrap(clazz);
2028 m = (methodinfo *) methodID;
2030 va_start(ap, methodID);
2031 _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
2036 void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
2037 jmethodID methodID, va_list args)
2043 o = (java_handle_t *) obj;
2044 c = LLNI_classinfo_unwrap(clazz);
2045 m = (methodinfo *) methodID;
2047 _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
2051 void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2052 jmethodID methodID, const jvalue * args)
2058 o = (java_handle_t *) obj;
2059 c = LLNI_classinfo_unwrap(clazz);
2060 m = (methodinfo *) methodID;
2062 _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2066 /* Accessing Fields of Objects ************************************************/
2068 /* GetFieldID ******************************************************************
2070 Returns the field ID for an instance (nonstatic) field of a
2071 class. The field is specified by its name and signature. The
2072 Get<type>Field and Set<type>Field families of accessor functions
2073 use field IDs to retrieve object fields.
2075 *******************************************************************************/
2077 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2085 STATISTICS(jniinvokation());
2087 c = LLNI_classinfo_unwrap(clazz);
2089 /* XXX NPE check? */
2091 uname = utf_new_char((char *) name);
2092 udesc = utf_new_char((char *) sig);
2094 f = class_findfield(c, uname, udesc);
2097 exceptions_throw_nosuchfielderror(c, uname);
2099 return (jfieldID) f;
2103 /* Get<type>Field Routines *****************************************************
2105 This family of accessor routines returns the value of an instance
2106 (nonstatic) field of an object. The field to access is specified by
2107 a field ID obtained by calling GetFieldID().
2109 *******************************************************************************/
2111 #define GET_FIELD(o,type,f) \
2112 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2114 #define JNI_GET_FIELD(name, type, intern) \
2115 type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2119 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2121 LLNI_CRITICAL_START; \
2123 ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2125 LLNI_CRITICAL_END; \
2127 return (type) ret; \
2130 JNI_GET_FIELD(Boolean, jboolean, s4)
2131 JNI_GET_FIELD(Byte, jbyte, s4)
2132 JNI_GET_FIELD(Char, jchar, s4)
2133 JNI_GET_FIELD(Short, jshort, s4)
2134 JNI_GET_FIELD(Int, jint, s4)
2135 JNI_GET_FIELD(Long, jlong, s8)
2136 JNI_GET_FIELD(Float, jfloat, float)
2137 JNI_GET_FIELD(Double, jdouble, double)
2140 jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2144 TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2146 LLNI_CRITICAL_START;
2148 o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2152 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2156 /* Set<type>Field Routines *****************************************************
2158 This family of accessor routines sets the value of an instance
2159 (nonstatic) field of an object. The field to access is specified by
2160 a field ID obtained by calling GetFieldID().
2162 *******************************************************************************/
2164 #define SET_FIELD(o,type,f,value) \
2165 *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2167 #define JNI_SET_FIELD(name, type, intern) \
2168 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2171 TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2173 LLNI_CRITICAL_START; \
2175 SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2177 LLNI_CRITICAL_START; \
2180 JNI_SET_FIELD(Boolean, jboolean, s4)
2181 JNI_SET_FIELD(Byte, jbyte, s4)
2182 JNI_SET_FIELD(Char, jchar, s4)
2183 JNI_SET_FIELD(Short, jshort, s4)
2184 JNI_SET_FIELD(Int, jint, s4)
2185 JNI_SET_FIELD(Long, jlong, s8)
2186 JNI_SET_FIELD(Float, jfloat, float)
2187 JNI_SET_FIELD(Double, jdouble, double)
2190 void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2193 TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2195 LLNI_CRITICAL_START;
2197 SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2203 /* Calling Static Methods *****************************************************/
2205 /* GetStaticMethodID ***********************************************************
2207 Returns the method ID for a static method of a class. The method is
2208 specified by its name and signature.
2210 GetStaticMethodID() causes an uninitialized class to be
2213 *******************************************************************************/
2215 jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2223 TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2225 c = LLNI_classinfo_unwrap(clazz);
2230 if (!(c->state & CLASS_INITIALIZED))
2231 if (!initialize_class(c))
2234 /* try to get the static method of the class */
2236 uname = utf_new_char((char *) name);
2237 udesc = utf_new_char((char *) sig);
2239 m = class_resolvemethod(c, uname, udesc);
2241 if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2242 exceptions_throw_nosuchmethoderror(c, uname, udesc);
2247 return (jmethodID) m;
2251 #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2252 type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2253 jmethodID methodID, ...) \
2259 m = (methodinfo *) methodID; \
2261 va_start(ap, methodID); \
2262 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2268 JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2269 JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2270 JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2271 JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2272 JNI_CALL_STATIC_METHOD(Int, jint, Int)
2273 JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2274 JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2275 JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2278 #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2279 type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2280 jmethodID methodID, va_list args) \
2285 m = (methodinfo *) methodID; \
2287 res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2292 JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2293 JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2294 JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2295 JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2296 JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2297 JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2298 JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2299 JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2302 #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2303 type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2304 jmethodID methodID, const jvalue *args) \
2309 m = (methodinfo *) methodID; \
2311 res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2316 JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2317 JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2318 JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2319 JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2320 JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2321 JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2322 JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2323 JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2326 jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2327 jmethodID methodID, ...)
2333 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2335 m = (methodinfo *) methodID;
2337 va_start(ap, methodID);
2338 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2341 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2345 jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2346 jmethodID methodID, va_list args)
2351 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2353 m = (methodinfo *) methodID;
2355 o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2357 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2361 jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2362 jmethodID methodID, const jvalue *args)
2367 TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2369 m = (methodinfo *) methodID;
2371 o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2373 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2377 void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2378 jmethodID methodID, ...)
2383 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2385 m = (methodinfo *) methodID;
2387 va_start(ap, methodID);
2388 _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2393 void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2394 jmethodID methodID, va_list args)
2398 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2400 m = (methodinfo *) methodID;
2402 _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2406 void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2407 jmethodID methodID, const jvalue * args)
2411 TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2413 m = (methodinfo *) methodID;
2415 _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2419 /* Accessing Static Fields ****************************************************/
2421 /* GetStaticFieldID ************************************************************
2423 Returns the field ID for a static field of a class. The field is
2424 specified by its name and signature. The GetStatic<type>Field and
2425 SetStatic<type>Field families of accessor functions use field IDs
2426 to retrieve static fields.
2428 *******************************************************************************/
2430 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2438 STATISTICS(jniinvokation());
2440 c = LLNI_classinfo_unwrap(clazz);
2442 uname = utf_new_char((char *) name);
2443 usig = utf_new_char((char *) sig);
2445 f = class_findfield(c, uname, usig);
2448 exceptions_throw_nosuchfielderror(c, uname);
2450 return (jfieldID) f;
2454 /* GetStatic<type>Field ********************************************************
2456 This family of accessor routines returns the value of a static
2459 *******************************************************************************/
2461 #define JNI_GET_STATIC_FIELD(name, type, field) \
2462 type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2468 STATISTICS(jniinvokation()); \
2470 c = LLNI_classinfo_unwrap(clazz); \
2471 f = (fieldinfo *) fieldID; \
2473 if (!(c->state & CLASS_INITIALIZED)) \
2474 if (!initialize_class(c)) \
2477 return f->value->field; \
2480 JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2481 JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2482 JNI_GET_STATIC_FIELD(Char, jchar, i)
2483 JNI_GET_STATIC_FIELD(Short, jshort, i)
2484 JNI_GET_STATIC_FIELD(Int, jint, i)
2485 JNI_GET_STATIC_FIELD(Long, jlong, l)
2486 JNI_GET_STATIC_FIELD(Float, jfloat, f)
2487 JNI_GET_STATIC_FIELD(Double, jdouble, d)
2490 jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2497 STATISTICS(jniinvokation());
2499 c = LLNI_classinfo_unwrap(clazz);
2500 f = (fieldinfo *) fieldID;
2502 if (!(c->state & CLASS_INITIALIZED))
2503 if (!initialize_class(c))
2506 h = LLNI_WRAP(f->value->a);
2508 return _Jv_JNI_NewLocalRef(env, (jobject) h);
2512 /* SetStatic<type>Field *******************************************************
2514 This family of accessor routines sets the value of a static field
2517 *******************************************************************************/
2519 #define JNI_SET_STATIC_FIELD(name, type, field) \
2520 void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2527 STATISTICS(jniinvokation()); \
2529 c = LLNI_classinfo_unwrap(clazz); \
2530 f = (fieldinfo *) fieldID; \
2532 if (!(c->state & CLASS_INITIALIZED)) \
2533 if (!initialize_class(c)) \
2536 f->value->field = value; \
2539 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2540 JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2541 JNI_SET_STATIC_FIELD(Char, jchar, i)
2542 JNI_SET_STATIC_FIELD(Short, jshort, i)
2543 JNI_SET_STATIC_FIELD(Int, jint, i)
2544 JNI_SET_STATIC_FIELD(Long, jlong, l)
2545 JNI_SET_STATIC_FIELD(Float, jfloat, f)
2546 JNI_SET_STATIC_FIELD(Double, jdouble, d)
2549 void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2555 STATISTICS(jniinvokation());
2557 c = LLNI_classinfo_unwrap(clazz);
2558 f = (fieldinfo *) fieldID;
2560 if (!(c->state & CLASS_INITIALIZED))
2561 if (!initialize_class(c))
2564 f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2568 /* String Operations **********************************************************/
2570 /* NewString *******************************************************************
2572 Create new java.lang.String object from an array of Unicode
2575 *******************************************************************************/
2577 jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
2579 java_lang_String *s;
2580 java_handle_chararray_t *a;
2583 STATISTICS(jniinvokation());
2585 s = (java_lang_String *) builtin_new(class_java_lang_String);
2586 a = builtin_newarray_char(len);
2588 /* javastring or characterarray could not be created */
2589 if ((a == NULL) || (s == NULL))
2593 for (i = 0; i < len; i++)
2594 LLNI_array_direct(a, i) = buf[i];
2596 LLNI_field_set_ref(s, value , a);
2597 LLNI_field_set_val(s, offset, 0);
2598 LLNI_field_set_val(s, count , len);
2600 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2604 static jchar emptyStringJ[]={0,0};
2606 /* GetStringLength *************************************************************
2608 Returns the length (the count of Unicode characters) of a Java
2611 *******************************************************************************/
2613 jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
2615 java_lang_String *s;
2618 TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
2620 s = (java_lang_String *) str;
2622 LLNI_field_get_val(s, count, len);
2628 /******************** convertes javastring to u2-array ****************************/
2630 u2 *javastring_tou2(jstring so)
2632 java_lang_String *s;
2633 java_handle_chararray_t *a;
2639 STATISTICS(jniinvokation());
2641 s = (java_lang_String *) so;
2646 LLNI_field_get_ref(s, value, a);
2651 LLNI_field_get_val(s, count, count);
2652 LLNI_field_get_val(s, offset, offset);
2654 /* allocate memory */
2656 stringbuffer = MNEW(u2, count + 1);
2660 for (i = 0; i < count; i++)
2661 stringbuffer[i] = LLNI_array_direct(a, offset + i);
2663 /* terminate string */
2665 stringbuffer[i] = '\0';
2667 return stringbuffer;
2671 /* GetStringChars **************************************************************
2673 Returns a pointer to the array of Unicode characters of the
2674 string. This pointer is valid until ReleaseStringChars() is called.
2676 *******************************************************************************/
2678 const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2682 STATISTICS(jniinvokation());
2684 jc = javastring_tou2(str);
2696 return emptyStringJ;
2700 /* ReleaseStringChars **********************************************************
2702 Informs the VM that the native code no longer needs access to
2703 chars. The chars argument is a pointer obtained from string using
2706 *******************************************************************************/
2708 void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2710 java_lang_String *s;
2712 STATISTICS(jniinvokation());
2714 if (chars == emptyStringJ)
2717 s = (java_lang_String *) str;
2719 MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
2723 /* NewStringUTF ****************************************************************
2725 Constructs a new java.lang.String object from an array of UTF-8
2728 *******************************************************************************/
2730 jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
2732 java_lang_String *s;
2734 TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2736 s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
2738 return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
2742 /****************** returns the utf8 length in bytes of a string *******************/
2744 jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
2746 java_lang_String *s;
2749 TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
2751 s = (java_lang_String *) string;
2753 length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
2759 /* GetStringUTFChars ***********************************************************
2761 Returns a pointer to an array of UTF-8 characters of the
2762 string. This array is valid until it is released by
2763 ReleaseStringUTFChars().
2765 *******************************************************************************/
2767 const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2772 STATISTICS(jniinvokation());
2780 u = javastring_toutf((java_handle_t *) string, false);
2789 /* ReleaseStringUTFChars *******************************************************
2791 Informs the VM that the native code no longer needs access to
2792 utf. The utf argument is a pointer derived from string using
2793 GetStringUTFChars().
2795 *******************************************************************************/
2797 void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2799 STATISTICS(jniinvokation());
2801 /* XXX we don't release utf chars right now, perhaps that should be done
2802 later. Since there is always one reference the garbage collector will
2807 /* Array Operations ***********************************************************/
2809 /* GetArrayLength **************************************************************
2811 Returns the number of elements in the array.
2813 *******************************************************************************/
2815 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2820 TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2822 a = (java_handle_t *) array;
2824 size = LLNI_array_size(a);
2830 /* NewObjectArray **************************************************************
2832 Constructs a new array holding objects in class elementClass. All
2833 elements are initially set to initialElement.
2835 *******************************************************************************/
2837 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2838 jclass elementClass, jobject initialElement)
2842 java_handle_objectarray_t *oa;
2845 STATISTICS(jniinvokation());
2847 c = LLNI_classinfo_unwrap(elementClass);
2848 o = (java_handle_t *) initialElement;
2851 exceptions_throw_negativearraysizeexception();
2855 oa = builtin_anewarray(length, c);
2860 /* set all elements to initialElement */
2862 for (i = 0; i < length; i++)
2863 array_objectarray_element_set(oa, i, o);
2865 return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
2869 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2872 java_handle_objectarray_t *oa;
2875 STATISTICS(jniinvokation());
2877 oa = (java_handle_objectarray_t *) array;
2879 if (index >= LLNI_array_size(oa)) {
2880 exceptions_throw_arrayindexoutofboundsexception();
2884 o = array_objectarray_element_get(oa, index);
2886 return _Jv_JNI_NewLocalRef(env, (jobject) o);
2890 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2891 jsize index, jobject val)
2893 java_handle_objectarray_t *oa;
2896 STATISTICS(jniinvokation());
2898 oa = (java_handle_objectarray_t *) array;
2899 o = (java_handle_t *) val;
2901 if (index >= LLNI_array_size(oa)) {
2902 exceptions_throw_arrayindexoutofboundsexception();
2906 /* check if the class of value is a subclass of the element class
2909 if (!builtin_canstore(oa, o))
2912 array_objectarray_element_set(oa, index, o);
2916 #define JNI_NEW_ARRAY(name, type, intern) \
2917 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2919 java_handle_##intern##array_t *a; \
2921 STATISTICS(jniinvokation()); \
2924 exceptions_throw_negativearraysizeexception(); \
2928 a = builtin_newarray_##intern(len); \
2930 return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
2933 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
2934 JNI_NEW_ARRAY(Byte, jbyteArray, byte)
2935 JNI_NEW_ARRAY(Char, jcharArray, char)
2936 JNI_NEW_ARRAY(Short, jshortArray, short)
2937 JNI_NEW_ARRAY(Int, jintArray, int)
2938 JNI_NEW_ARRAY(Long, jlongArray, long)
2939 JNI_NEW_ARRAY(Float, jfloatArray, float)
2940 JNI_NEW_ARRAY(Double, jdoubleArray, double)
2943 /* Get<PrimitiveType>ArrayElements *********************************************
2945 A family of functions that returns the body of the primitive array.
2947 *******************************************************************************/
2949 #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2950 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2953 java_handle_##intern##array_t *a; \
2955 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2957 a = (java_handle_##intern##array_t *) array; \
2960 *isCopy = JNI_FALSE; \
2962 return (type *) LLNI_array_data(a); \
2965 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2966 JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2967 JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2968 JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2969 JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2970 JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2971 JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2972 JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2975 /* Release<PrimitiveType>ArrayElements *****************************************
2977 A family of functions that informs the VM that the native code no
2978 longer needs access to elems. The elems argument is a pointer
2979 derived from array using the corresponding
2980 Get<PrimitiveType>ArrayElements() function. If necessary, this
2981 function copies back all changes made to elems to the original
2984 *******************************************************************************/
2986 #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2987 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2988 type *elems, jint mode) \
2990 java_handle_##intern##array_t *a; \
2992 STATISTICS(jniinvokation()); \
2994 a = (java_handle_##intern##array_t *) array; \
2996 if (elems != (type *) LLNI_array_data(a)) { \
2999 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3002 MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
3003 /* XXX TWISTI how should it be freed? */ \
3006 /* XXX TWISTI how should it be freed? */ \
3012 JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
3013 JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
3014 JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
3015 JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
3016 JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
3017 JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
3018 JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
3019 JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
3022 /* Get<PrimitiveType>ArrayRegion **********************************************
3024 A family of functions that copies a region of a primitive array
3027 *******************************************************************************/
3029 #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
3030 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
3031 jsize start, jsize len, type *buf) \
3033 java_handle_##intern##array_t *a; \
3035 TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
3037 a = (java_handle_##intern##array_t *) array; \
3039 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3040 exceptions_throw_arrayindexoutofboundsexception(); \
3042 MCOPY(buf, &LLNI_array_direct(a, start), intern2, len); \
3045 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3046 JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
3047 JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
3048 JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
3049 JNI_GET_ARRAY_REGION(Int, jint, int, s4)
3050 JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
3051 JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
3052 JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
3055 /* Set<PrimitiveType>ArrayRegion **********************************************
3057 A family of functions that copies back a region of a primitive
3058 array from a buffer.
3060 *******************************************************************************/
3062 #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
3063 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
3064 jsize start, jsize len, const type *buf) \
3066 java_handle_##intern##array_t *a; \
3068 STATISTICS(jniinvokation()); \
3070 a = (java_handle_##intern##array_t *) array; \
3072 if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
3073 exceptions_throw_arrayindexoutofboundsexception(); \
3075 MCOPY(&LLNI_array_direct(a, start), buf, intern2, len); \
3078 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
3079 JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
3080 JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
3081 JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
3082 JNI_SET_ARRAY_REGION(Int, jint, int, s4)
3083 JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
3084 JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
3085 JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
3088 /* Registering Native Methods *************************************************/
3090 /* RegisterNatives *************************************************************
3092 Registers native methods with the class specified by the clazz
3093 argument. The methods parameter specifies an array of
3094 JNINativeMethod structures that contain the names, signatures, and
3095 function pointers of the native methods. The nMethods parameter
3096 specifies the number of native methods in the array.
3098 *******************************************************************************/
3100 jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
3101 const JNINativeMethod *methods, jint nMethods)
3105 STATISTICS(jniinvokation());
3107 c = LLNI_classinfo_unwrap(clazz);
3109 /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
3110 if (jvmti) jvmti_NativeMethodBind(method, address, new_address_ptr);
3113 native_method_register(c->name, methods, nMethods);
3119 /* UnregisterNatives ***********************************************************
3121 Unregisters native methods of a class. The class goes back to the
3122 state before it was linked or registered with its native method
3125 This function should not be used in normal native code. Instead, it
3126 provides special programs a way to reload and relink native
3129 *******************************************************************************/
3131 jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3133 STATISTICS(jniinvokation());
3135 /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3137 log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3143 /* Monitor Operations *********************************************************/
3145 /* MonitorEnter ****************************************************************
3147 Enters the monitor associated with the underlying Java object
3150 *******************************************************************************/
3152 jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3154 STATISTICS(jniinvokation());
3157 exceptions_throw_nullpointerexception();
3161 LOCK_MONITOR_ENTER(obj);
3167 /* MonitorExit *****************************************************************
3169 The current thread must be the owner of the monitor associated with
3170 the underlying Java object referred to by obj. The thread
3171 decrements the counter indicating the number of times it has
3172 entered this monitor. If the value of the counter becomes zero, the
3173 current thread releases the monitor.
3175 *******************************************************************************/
3177 jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3179 STATISTICS(jniinvokation());
3182 exceptions_throw_nullpointerexception();
3186 LOCK_MONITOR_EXIT(obj);
3192 /* JavaVM Interface ***********************************************************/
3194 /* GetJavaVM *******************************************************************
3196 Returns the Java VM interface (used in the Invocation API)
3197 associated with the current thread. The result is placed at the
3198 location pointed to by the second argument, vm.
3200 *******************************************************************************/
3202 jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
3204 STATISTICS(jniinvokation());
3206 *vm = (JavaVM *) _Jv_jvm;
3212 /* GetStringRegion *************************************************************
3214 Copies len number of Unicode characters beginning at offset start
3215 to the given buffer buf.
3217 Throws StringIndexOutOfBoundsException on index overflow.
3219 *******************************************************************************/
3221 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
3224 java_lang_String *s;
3225 java_handle_chararray_t *ca;
3227 STATISTICS(jniinvokation());
3229 s = (java_lang_String *) str;
3230 LLNI_field_get_ref(s, value, ca);
3232 if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
3233 (start + len > LLNI_field_direct(s, count))) {
3234 exceptions_throw_stringindexoutofboundsexception();
3238 MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
3242 /* GetStringUTFRegion **********************************************************
3244 Translates len number of Unicode characters beginning at offset
3245 start into UTF-8 format and place the result in the given buffer
3248 Throws StringIndexOutOfBoundsException on index overflow.
3250 *******************************************************************************/
3252 void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
3253 jsize len, char *buf)
3255 java_lang_String *s;
3256 java_handle_chararray_t *ca;
3261 TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3263 s = (java_lang_String *) str;
3264 LLNI_field_get_ref(s, value, ca);
3265 LLNI_field_get_val(s, count, count);
3266 LLNI_field_get_val(s, offset, offset);
3268 if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3269 exceptions_throw_stringindexoutofboundsexception();
3273 for (i = 0; i < len; i++)
3274 buf[i] = LLNI_array_direct(ca, offset + start + i);
3280 /* GetPrimitiveArrayCritical ***************************************************
3282 Obtain a direct pointer to array elements.
3284 *******************************************************************************/
3286 void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
3289 java_handle_bytearray_t *ba;
3292 ba = (java_handle_bytearray_t *) array;
3294 /* do the same as Kaffe does */
3296 bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
3302 /* ReleasePrimitiveArrayCritical ***********************************************
3304 No specific documentation.
3306 *******************************************************************************/
3308 void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
3309 void *carray, jint mode)
3311 STATISTICS(jniinvokation());
3313 /* do the same as Kaffe does */
3315 _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
3320 /* GetStringCritical ***********************************************************
3322 The semantics of these two functions are similar to the existing
3323 Get/ReleaseStringChars functions.
3325 *******************************************************************************/
3327 const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3330 STATISTICS(jniinvokation());
3332 return _Jv_JNI_GetStringChars(env, string, isCopy);
3336 void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3337 const jchar *cstring)
3339 STATISTICS(jniinvokation());
3341 _Jv_JNI_ReleaseStringChars(env, string, cstring);
3345 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3347 TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3353 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3355 TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3359 /* NewGlobalRef ****************************************************************
3361 Creates a new global reference to the object referred to by the obj
3364 *******************************************************************************/
3366 jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
3368 hashtable_global_ref_entry *gre;
3369 u4 key; /* hashkey */
3370 u4 slot; /* slot in hashtable */
3373 STATISTICS(jniinvokation());
3375 o = (java_handle_t *) obj;
3377 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3379 LLNI_CRITICAL_START;
3381 /* normally addresses are aligned to 4, 8 or 16 bytes */
3383 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3384 slot = key & (hashtable_global_ref->size - 1);
3385 gre = hashtable_global_ref->ptr[slot];
3387 /* search external hash chain for the entry */
3390 if (gre->o == LLNI_DIRECT(o)) {
3391 /* global object found, increment the reference */
3398 gre = gre->hashlink; /* next element in external chain */
3403 /* global ref not found, create a new one */
3406 gre = NEW(hashtable_global_ref_entry);
3408 #if defined(ENABLE_GC_CACAO)
3409 /* register global ref with the GC */
3411 gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3414 LLNI_CRITICAL_START;
3416 gre->o = LLNI_DIRECT(o);
3421 /* insert entry into hashtable */
3423 gre->hashlink = hashtable_global_ref->ptr[slot];
3425 hashtable_global_ref->ptr[slot] = gre;
3427 /* update number of hashtable-entries */
3429 hashtable_global_ref->entries++;
3432 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3434 #if defined(ENABLE_HANDLES)
3442 /* DeleteGlobalRef *************************************************************
3444 Deletes the global reference pointed to by globalRef.
3446 *******************************************************************************/
3448 void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3450 hashtable_global_ref_entry *gre;
3451 hashtable_global_ref_entry *prevgre;
3452 u4 key; /* hashkey */
3453 u4 slot; /* slot in hashtable */
3456 STATISTICS(jniinvokation());
3458 o = (java_handle_t *) globalRef;
3460 LOCK_MONITOR_ENTER(hashtable_global_ref->header);
3462 LLNI_CRITICAL_START;
3464 /* normally addresses are aligned to 4, 8 or 16 bytes */
3466 key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3467 slot = key & (hashtable_global_ref->size - 1);
3468 gre = hashtable_global_ref->ptr[slot];
3470 /* initialize prevgre */
3474 /* search external hash chain for the entry */
3477 if (gre->o == LLNI_DIRECT(o)) {
3478 /* global object found, decrement the reference count */
3482 /* if reference count is 0, remove the entry */
3484 if (gre->refs == 0) {
3485 /* special handling if it's the first in the chain */
3487 if (prevgre == NULL)
3488 hashtable_global_ref->ptr[slot] = gre->hashlink;
3490 prevgre->hashlink = gre->hashlink;
3492 #if defined(ENABLE_GC_CACAO)
3493 /* unregister global ref with the GC */
3495 gc_reference_unregister(&(gre->o));
3498 FREE(gre, hashtable_global_ref_entry);
3503 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3508 prevgre = gre; /* save current pointer for removal */
3509 gre = gre->hashlink; /* next element in external chain */
3512 log_println("JNI-DeleteGlobalRef: global reference not found");
3516 LOCK_MONITOR_EXIT(hashtable_global_ref->header);
3520 /* ExceptionCheck **************************************************************
3522 Returns JNI_TRUE when there is a pending exception; otherwise,
3525 *******************************************************************************/
3527 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3531 STATISTICS(jniinvokation());
3533 o = exceptions_get_exception();
3535 return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3539 /* New JNI 1.4 functions ******************************************************/
3541 /* NewDirectByteBuffer *********************************************************
3543 Allocates and returns a direct java.nio.ByteBuffer referring to the
3544 block of memory starting at the memory address address and
3545 extending capacity bytes.
3547 *******************************************************************************/
3549 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3551 #if defined(ENABLE_JAVASE)
3552 # if defined(WITH_CLASSPATH_GNU)
3553 java_handle_t *nbuf;
3555 # if SIZEOF_VOID_P == 8
3556 gnu_classpath_Pointer64 *paddress;
3558 gnu_classpath_Pointer32 *paddress;
3561 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3563 /* alocate a gnu.classpath.Pointer{32,64} object */
3565 # if SIZEOF_VOID_P == 8
3566 if (!(paddress = (gnu_classpath_Pointer64 *)
3567 builtin_new(class_gnu_classpath_Pointer64)))
3569 if (!(paddress = (gnu_classpath_Pointer32 *)
3570 builtin_new(class_gnu_classpath_Pointer32)))
3574 /* fill gnu.classpath.Pointer{32,64} with address */
3576 LLNI_field_set_val(paddress, data, (ptrint) address);
3578 /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
3580 nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
3581 (jmethodID) dbbirw_init, NULL, paddress,
3582 (jint) capacity, (jint) capacity, (jint) 0);
3584 /* add local reference and return the value */
3586 return _Jv_JNI_NewLocalRef(env, nbuf);
3588 # elif defined(WITH_CLASSPATH_SUN)
3594 TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
3596 /* Be paranoid about address sign-extension. */
3598 addr = (int64_t) ((uintptr_t) address);
3599 cap = (int32_t) capacity;
3601 o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3602 (jmethodID) dbb_init, addr, cap);
3604 /* Add local reference and return the value. */
3606 return _Jv_JNI_NewLocalRef(env, o);
3609 # error unknown classpath configuration
3613 vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
3615 /* keep compiler happy */
3622 /* GetDirectBufferAddress ******************************************************
3624 Fetches and returns the starting address of the memory region
3625 referenced by the given direct java.nio.Buffer.
3627 *******************************************************************************/
3629 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3631 #if defined(ENABLE_JAVASE)
3634 # if defined(WITH_CLASSPATH_GNU)
3636 java_nio_DirectByteBufferImpl *nbuf;
3637 gnu_classpath_Pointer *po;
3638 # if SIZEOF_VOID_P == 8
3639 gnu_classpath_Pointer64 *paddress;
3642 gnu_classpath_Pointer32 *paddress;
3647 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3649 /* Prevent compiler warning. */
3651 h = (java_handle_t *) buf;
3653 if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3656 nbuf = (java_nio_DirectByteBufferImpl *) buf;
3658 LLNI_field_get_ref(nbuf, address, po);
3660 # if SIZEOF_VOID_P == 8
3661 paddress = (gnu_classpath_Pointer64 *) po;
3663 paddress = (gnu_classpath_Pointer32 *) po;
3666 if (paddress == NULL)
3669 LLNI_field_get_val(paddress, data, address);
3671 p = (void *) (intptr_t) address;
3675 # elif defined(WITH_CLASSPATH_SUN)
3681 TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3683 /* Prevent compiler warning. */
3685 h = (java_handle_t *) buf;
3687 if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
3690 o = (java_nio_Buffer *) buf;
3692 LLNI_field_get_val(o, address, address);
3694 p = (void *) (intptr_t) address;
3699 # error unknown classpath configuration
3704 vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
3706 /* keep compiler happy */
3714 /* GetDirectBufferCapacity *****************************************************
3716 Fetches and returns the capacity in bytes of the memory region
3717 referenced by the given direct java.nio.Buffer.
3719 *******************************************************************************/
3721 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3723 #if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
3725 java_nio_Buffer *nbuf;
3728 STATISTICS(jniinvokation());
3730 o = (java_handle_t *) buf;
3732 if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
3735 nbuf = (java_nio_Buffer *) o;
3737 LLNI_field_get_val(nbuf, cap, capacity);
3741 vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
3743 /* keep compiler happy */
3750 /* GetObjectRefType ************************************************************
3752 Returns the type of the object referred to by the obj argument. The
3753 argument obj can either be a local, global or weak global
3756 *******************************************************************************/
3758 jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3760 log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3766 /* DestroyJavaVM ***************************************************************
3768 Unloads a Java VM and reclaims its resources. Only the main thread
3769 can unload the VM. The system waits until the main thread is only
3770 remaining user thread before it destroys the VM.
3772 *******************************************************************************/
3774 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
3778 TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
3780 if (vm_created == false)
3783 status = vm_destroy(vm);
3789 /* AttachCurrentThread *********************************************************
3791 Attaches the current thread to a Java VM. Returns a JNI interface
3792 pointer in the JNIEnv argument.
3794 Trying to attach a thread that is already attached is a no-op.
3796 A native thread cannot be attached simultaneously to two Java VMs.
3798 When a thread is attached to the VM, the context class loader is
3799 the bootstrap loader.
3801 *******************************************************************************/
3803 static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3805 #if defined(ENABLE_THREADS)
3806 JavaVMAttachArgs *vm_aargs;
3809 /* If the current thread has already been attached, this operation
3812 result = thread_current_is_attached();
3814 if (result == true) {
3820 vm_aargs = (JavaVMAttachArgs *) thr_args;
3822 if (vm_aargs != NULL) {
3823 if ((vm_aargs->version != JNI_VERSION_1_2) &&
3824 (vm_aargs->version != JNI_VERSION_1_4))
3825 return JNI_EVERSION;
3828 if (!threads_attach_current_thread(vm_aargs, false))
3831 if (!localref_table_init())
3841 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
3845 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
3847 if (vm_created == false)
3850 result = jni_attach_current_thread(p_env, thr_args, false);
3856 /* DetachCurrentThread *********************************************************
3858 Detaches the current thread from a Java VM. All Java monitors held
3859 by this thread are released. All Java threads waiting for this
3860 thread to die are notified.
3862 In JDK 1.1, the main thread cannot be detached from the VM. It must
3863 call DestroyJavaVM to unload the entire VM.
3865 In the JDK, the main thread can be detached from the VM.
3867 The main thread, which is the thread that created the Java VM,
3868 cannot be detached from the VM. Instead, the main thread must call
3869 JNI_DestroyJavaVM() to unload the entire VM.
3871 *******************************************************************************/
3873 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
3875 #if defined(ENABLE_THREADS)
3879 TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
3881 t = thread_get_current();
3887 /* If the given thread has already been detached, this operation
3890 result = thread_is_attached(t);
3892 if (result == false)
3895 /* We need to pop all frames before we can destroy the table. */
3897 localref_frame_pop_all();
3899 if (!localref_table_destroy())
3902 if (!threads_detach_thread(t))
3910 /* GetEnv **********************************************************************
3912 If the current thread is not attached to the VM, sets *env to NULL,
3913 and returns JNI_EDETACHED. If the specified version is not
3914 supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3915 sets *env to the appropriate interface, and returns JNI_OK.
3917 *******************************************************************************/
3919 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
3921 TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
3923 if (vm_created == false) {
3925 return JNI_EDETACHED;
3928 #if defined(ENABLE_THREADS)
3929 if (thread_get_current() == NULL) {
3932 return JNI_EDETACHED;
3936 /* Check the JNI version. */
3938 if (jni_version_check(version) == true) {
3943 #if defined(ENABLE_JVMTI)
3944 if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE)
3945 == JVMTI_VERSION_INTERFACE_JVMTI) {
3947 *env = (void *) jvmti_new_environment();
3956 return JNI_EVERSION;
3960 /* AttachCurrentThreadAsDaemon *************************************************
3962 Same semantics as AttachCurrentThread, but the newly-created
3963 java.lang.Thread instance is a daemon.
3965 If the thread has already been attached via either
3966 AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3967 simply sets the value pointed to by penv to the JNIEnv of the
3968 current thread. In this case neither AttachCurrentThread nor this
3969 routine have any effect on the daemon status of the thread.
3971 *******************************************************************************/
3973 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
3977 TRACEJNICALLS(("_Jv_JNI_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
3979 if (vm_created == false)
3982 result = jni_attach_current_thread(penv, args, true);
3988 /* JNI invocation table *******************************************************/
3990 const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3995 _Jv_JNI_DestroyJavaVM,
3996 _Jv_JNI_AttachCurrentThread,
3997 _Jv_JNI_DetachCurrentThread,
3999 _Jv_JNI_AttachCurrentThreadAsDaemon
4003 /* JNI function table *********************************************************/
4005 struct JNINativeInterface_ _Jv_JNINativeInterface = {
4012 _Jv_JNI_DefineClass,
4014 jni_FromReflectedMethod,
4015 jni_FromReflectedField,
4016 _Jv_JNI_ToReflectedMethod,
4017 _Jv_JNI_GetSuperclass,
4018 _Jv_JNI_IsAssignableFrom,
4019 _Jv_JNI_ToReflectedField,
4023 _Jv_JNI_ExceptionOccurred,
4024 jni_ExceptionDescribe,
4027 _Jv_JNI_PushLocalFrame,
4028 _Jv_JNI_PopLocalFrame,
4030 _Jv_JNI_NewGlobalRef,
4031 _Jv_JNI_DeleteGlobalRef,
4032 _Jv_JNI_DeleteLocalRef,
4033 _Jv_JNI_IsSameObject,
4034 _Jv_JNI_NewLocalRef,
4035 _Jv_JNI_EnsureLocalCapacity,
4037 _Jv_JNI_AllocObject,
4042 _Jv_JNI_GetObjectClass,
4043 _Jv_JNI_IsInstanceOf,
4045 _Jv_JNI_GetMethodID,
4047 _Jv_JNI_CallObjectMethod,
4048 _Jv_JNI_CallObjectMethodV,
4049 _Jv_JNI_CallObjectMethodA,
4050 _Jv_JNI_CallBooleanMethod,
4051 _Jv_JNI_CallBooleanMethodV,
4052 _Jv_JNI_CallBooleanMethodA,
4053 _Jv_JNI_CallByteMethod,
4054 _Jv_JNI_CallByteMethodV,
4055 _Jv_JNI_CallByteMethodA,
4056 _Jv_JNI_CallCharMethod,
4057 _Jv_JNI_CallCharMethodV,
4058 _Jv_JNI_CallCharMethodA,
4059 _Jv_JNI_CallShortMethod,
4060 _Jv_JNI_CallShortMethodV,
4061 _Jv_JNI_CallShortMethodA,
4062 _Jv_JNI_CallIntMethod,
4063 _Jv_JNI_CallIntMethodV,
4064 _Jv_JNI_CallIntMethodA,
4065 _Jv_JNI_CallLongMethod,
4066 _Jv_JNI_CallLongMethodV,
4067 _Jv_JNI_CallLongMethodA,
4068 _Jv_JNI_CallFloatMethod,
4069 _Jv_JNI_CallFloatMethodV,
4070 _Jv_JNI_CallFloatMethodA,
4071 _Jv_JNI_CallDoubleMethod,
4072 _Jv_JNI_CallDoubleMethodV,
4073 _Jv_JNI_CallDoubleMethodA,
4074 _Jv_JNI_CallVoidMethod,
4075 _Jv_JNI_CallVoidMethodV,
4076 _Jv_JNI_CallVoidMethodA,
4078 _Jv_JNI_CallNonvirtualObjectMethod,
4079 _Jv_JNI_CallNonvirtualObjectMethodV,
4080 _Jv_JNI_CallNonvirtualObjectMethodA,
4081 _Jv_JNI_CallNonvirtualBooleanMethod,
4082 _Jv_JNI_CallNonvirtualBooleanMethodV,
4083 _Jv_JNI_CallNonvirtualBooleanMethodA,
4084 _Jv_JNI_CallNonvirtualByteMethod,
4085 _Jv_JNI_CallNonvirtualByteMethodV,
4086 _Jv_JNI_CallNonvirtualByteMethodA,
4087 _Jv_JNI_CallNonvirtualCharMethod,
4088 _Jv_JNI_CallNonvirtualCharMethodV,
4089 _Jv_JNI_CallNonvirtualCharMethodA,
4090 _Jv_JNI_CallNonvirtualShortMethod,
4091 _Jv_JNI_CallNonvirtualShortMethodV,
4092 _Jv_JNI_CallNonvirtualShortMethodA,
4093 _Jv_JNI_CallNonvirtualIntMethod,
4094 _Jv_JNI_CallNonvirtualIntMethodV,
4095 _Jv_JNI_CallNonvirtualIntMethodA,
4096 _Jv_JNI_CallNonvirtualLongMethod,
4097 _Jv_JNI_CallNonvirtualLongMethodV,
4098 _Jv_JNI_CallNonvirtualLongMethodA,
4099 _Jv_JNI_CallNonvirtualFloatMethod,
4100 _Jv_JNI_CallNonvirtualFloatMethodV,
4101 _Jv_JNI_CallNonvirtualFloatMethodA,
4102 _Jv_JNI_CallNonvirtualDoubleMethod,
4103 _Jv_JNI_CallNonvirtualDoubleMethodV,
4104 _Jv_JNI_CallNonvirtualDoubleMethodA,
4105 _Jv_JNI_CallNonvirtualVoidMethod,
4106 _Jv_JNI_CallNonvirtualVoidMethodV,
4107 _Jv_JNI_CallNonvirtualVoidMethodA,
4111 _Jv_JNI_GetObjectField,
4112 _Jv_JNI_GetBooleanField,
4113 _Jv_JNI_GetByteField,
4114 _Jv_JNI_GetCharField,
4115 _Jv_JNI_GetShortField,
4116 _Jv_JNI_GetIntField,
4117 _Jv_JNI_GetLongField,
4118 _Jv_JNI_GetFloatField,
4119 _Jv_JNI_GetDoubleField,
4120 _Jv_JNI_SetObjectField,
4121 _Jv_JNI_SetBooleanField,
4122 _Jv_JNI_SetByteField,
4123 _Jv_JNI_SetCharField,
4124 _Jv_JNI_SetShortField,
4125 _Jv_JNI_SetIntField,
4126 _Jv_JNI_SetLongField,
4127 _Jv_JNI_SetFloatField,
4128 _Jv_JNI_SetDoubleField,
4130 _Jv_JNI_GetStaticMethodID,
4132 _Jv_JNI_CallStaticObjectMethod,
4133 _Jv_JNI_CallStaticObjectMethodV,
4134 _Jv_JNI_CallStaticObjectMethodA,
4135 _Jv_JNI_CallStaticBooleanMethod,
4136 _Jv_JNI_CallStaticBooleanMethodV,
4137 _Jv_JNI_CallStaticBooleanMethodA,
4138 _Jv_JNI_CallStaticByteMethod,
4139 _Jv_JNI_CallStaticByteMethodV,
4140 _Jv_JNI_CallStaticByteMethodA,
4141 _Jv_JNI_CallStaticCharMethod,
4142 _Jv_JNI_CallStaticCharMethodV,
4143 _Jv_JNI_CallStaticCharMethodA,
4144 _Jv_JNI_CallStaticShortMethod,
4145 _Jv_JNI_CallStaticShortMethodV,
4146 _Jv_JNI_CallStaticShortMethodA,
4147 _Jv_JNI_CallStaticIntMethod,
4148 _Jv_JNI_CallStaticIntMethodV,
4149 _Jv_JNI_CallStaticIntMethodA,
4150 _Jv_JNI_CallStaticLongMethod,
4151 _Jv_JNI_CallStaticLongMethodV,
4152 _Jv_JNI_CallStaticLongMethodA,
4153 _Jv_JNI_CallStaticFloatMethod,
4154 _Jv_JNI_CallStaticFloatMethodV,
4155 _Jv_JNI_CallStaticFloatMethodA,
4156 _Jv_JNI_CallStaticDoubleMethod,
4157 _Jv_JNI_CallStaticDoubleMethodV,
4158 _Jv_JNI_CallStaticDoubleMethodA,
4159 _Jv_JNI_CallStaticVoidMethod,
4160 _Jv_JNI_CallStaticVoidMethodV,
4161 _Jv_JNI_CallStaticVoidMethodA,
4163 _Jv_JNI_GetStaticFieldID,
4165 _Jv_JNI_GetStaticObjectField,
4166 _Jv_JNI_GetStaticBooleanField,
4167 _Jv_JNI_GetStaticByteField,
4168 _Jv_JNI_GetStaticCharField,
4169 _Jv_JNI_GetStaticShortField,
4170 _Jv_JNI_GetStaticIntField,
4171 _Jv_JNI_GetStaticLongField,
4172 _Jv_JNI_GetStaticFloatField,
4173 _Jv_JNI_GetStaticDoubleField,
4174 _Jv_JNI_SetStaticObjectField,
4175 _Jv_JNI_SetStaticBooleanField,
4176 _Jv_JNI_SetStaticByteField,
4177 _Jv_JNI_SetStaticCharField,
4178 _Jv_JNI_SetStaticShortField,
4179 _Jv_JNI_SetStaticIntField,
4180 _Jv_JNI_SetStaticLongField,
4181 _Jv_JNI_SetStaticFloatField,
4182 _Jv_JNI_SetStaticDoubleField,
4185 _Jv_JNI_GetStringLength,
4186 _Jv_JNI_GetStringChars,
4187 _Jv_JNI_ReleaseStringChars,
4189 _Jv_JNI_NewStringUTF,
4190 _Jv_JNI_GetStringUTFLength,
4191 _Jv_JNI_GetStringUTFChars,
4192 _Jv_JNI_ReleaseStringUTFChars,
4194 _Jv_JNI_GetArrayLength,
4196 _Jv_JNI_NewObjectArray,
4197 _Jv_JNI_GetObjectArrayElement,
4198 _Jv_JNI_SetObjectArrayElement,
4200 _Jv_JNI_NewBooleanArray,
4201 _Jv_JNI_NewByteArray,
4202 _Jv_JNI_NewCharArray,
4203 _Jv_JNI_NewShortArray,
4204 _Jv_JNI_NewIntArray,
4205 _Jv_JNI_NewLongArray,
4206 _Jv_JNI_NewFloatArray,
4207 _Jv_JNI_NewDoubleArray,
4209 _Jv_JNI_GetBooleanArrayElements,
4210 _Jv_JNI_GetByteArrayElements,
4211 _Jv_JNI_GetCharArrayElements,
4212 _Jv_JNI_GetShortArrayElements,
4213 _Jv_JNI_GetIntArrayElements,
4214 _Jv_JNI_GetLongArrayElements,
4215 _Jv_JNI_GetFloatArrayElements,
4216 _Jv_JNI_GetDoubleArrayElements,
4218 _Jv_JNI_ReleaseBooleanArrayElements,
4219 _Jv_JNI_ReleaseByteArrayElements,
4220 _Jv_JNI_ReleaseCharArrayElements,
4221 _Jv_JNI_ReleaseShortArrayElements,
4222 _Jv_JNI_ReleaseIntArrayElements,
4223 _Jv_JNI_ReleaseLongArrayElements,
4224 _Jv_JNI_ReleaseFloatArrayElements,
4225 _Jv_JNI_ReleaseDoubleArrayElements,
4227 _Jv_JNI_GetBooleanArrayRegion,
4228 _Jv_JNI_GetByteArrayRegion,
4229 _Jv_JNI_GetCharArrayRegion,
4230 _Jv_JNI_GetShortArrayRegion,
4231 _Jv_JNI_GetIntArrayRegion,
4232 _Jv_JNI_GetLongArrayRegion,
4233 _Jv_JNI_GetFloatArrayRegion,
4234 _Jv_JNI_GetDoubleArrayRegion,
4235 _Jv_JNI_SetBooleanArrayRegion,
4236 _Jv_JNI_SetByteArrayRegion,
4237 _Jv_JNI_SetCharArrayRegion,
4238 _Jv_JNI_SetShortArrayRegion,
4239 _Jv_JNI_SetIntArrayRegion,
4240 _Jv_JNI_SetLongArrayRegion,
4241 _Jv_JNI_SetFloatArrayRegion,
4242 _Jv_JNI_SetDoubleArrayRegion,
4244 _Jv_JNI_RegisterNatives,
4245 _Jv_JNI_UnregisterNatives,
4247 _Jv_JNI_MonitorEnter,
4248 _Jv_JNI_MonitorExit,
4252 /* New JNI 1.2 functions. */
4254 _Jv_JNI_GetStringRegion,
4255 _Jv_JNI_GetStringUTFRegion,
4257 _Jv_JNI_GetPrimitiveArrayCritical,
4258 _Jv_JNI_ReleasePrimitiveArrayCritical,
4260 _Jv_JNI_GetStringCritical,
4261 _Jv_JNI_ReleaseStringCritical,
4263 _Jv_JNI_NewWeakGlobalRef,
4264 _Jv_JNI_DeleteWeakGlobalRef,
4266 _Jv_JNI_ExceptionCheck,
4268 /* New JNI 1.4 functions. */
4270 _Jv_JNI_NewDirectByteBuffer,
4271 _Jv_JNI_GetDirectBufferAddress,
4272 _Jv_JNI_GetDirectBufferCapacity,
4274 /* New JNI 1.6 functions. */
4276 jni_GetObjectRefType
4280 /* Invocation API Functions ***************************************************/
4282 /* JNI_GetDefaultJavaVMInitArgs ************************************************
4284 Returns a default configuration for the Java VM.
4286 *******************************************************************************/
4288 jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4290 JavaVMInitArgs *_vm_args;
4292 _vm_args = (JavaVMInitArgs *) vm_args;
4294 /* GNU classpath currently supports JNI 1.2 */
4296 switch (_vm_args->version) {
4297 case JNI_VERSION_1_1:
4298 _vm_args->version = JNI_VERSION_1_1;
4301 case JNI_VERSION_1_2:
4302 case JNI_VERSION_1_4:
4303 _vm_args->ignoreUnrecognized = JNI_FALSE;
4304 _vm_args->options = NULL;
4305 _vm_args->nOptions = 0;
4316 /* JNI_GetCreatedJavaVMs *******************************************************
4318 Returns all Java VMs that have been created. Pointers to VMs are written in
4319 the buffer vmBuf in the order they are created. At most bufLen number of
4320 entries will be written. The total number of created VMs is returned in
4323 *******************************************************************************/
4325 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4327 TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4332 /* We currently only support 1 VM running. */
4334 vmBuf[0] = (JavaVM *) _Jv_jvm;
4341 /* JNI_CreateJavaVM ************************************************************
4343 Loads and initializes a Java VM. The current thread becomes the main thread.
4344 Sets the env argument to the JNI interface pointer of the main thread.
4346 *******************************************************************************/
4348 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4350 TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4352 /* actually create the JVM */
4354 if (!vm_createjvm(p_vm, p_env, vm_args))
4362 * These are local overrides for various environment variables in Emacs.
4363 * Please do not remove this and leave it at the end of the file, where
4364 * Emacs will automagically detect them.
4365 * ---------------------------------------------------------------------
4368 * indent-tabs-mode: t
4372 * vim:noexpandtab:sw=4:ts=4: