1 /* Emacs Lisp binding to Java Native Interface.
2 Copyright (C) 2000 Daiki Ueno.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 #define JAVA_OS_CODING Fget_coding_system(Vjava_coding_system)
28 #define JAVA_OS_CODING Qnative
31 Lisp_Object Vjava_coding_system;
32 Lisp_Object Vjava_class_path;
33 Lisp_Object Vjava_library_path;
34 static Lisp_Object Qjava;
36 Lisp_Object Qjavaclassp;
37 Lisp_Object Qjavaobjectp;
39 static JavaVM *java_jvm = NULL;
40 static JNIEnv *java_env = NULL;
42 #define JAVAVM_LIVE_P() (java_jvm && java_env)
43 #define CHECK_LIVE_JAVAVM() do { \
44 if (!JAVAVM_LIVE_P ()) \
45 error ("Attempting to access uninitialized Java VM.\n"); \
48 static Extbyte *java_build_property_string (Lisp_Object, Lisp_Object);
49 static void java_dots_to_slashes (Extbyte *);
50 static int java_unify_parameter (JNIEnv *, const Extbyte *, Lisp_Object,
52 static Lisp_Object java_build_return_value (JNIEnv *, const Extbyte *, jvalue);
54 typedef jlong (JNICALL *jni_method_caller)
55 (JNIEnv *, jobject, jmethodID, jvalue *);
57 typedef jlong (JNICALL *jni_static_method_caller)
58 (JNIEnv *, jclass, jmethodID, jvalue *);
60 typedef jlong (JNICALL *jni_nonvirtual_method_caller)
61 (JNIEnv *, jobject, jclass, jmethodID, jvalue *);
63 typedef jarray (JNICALL *jni_array_allocater) (JNIEnv *, jsize);
65 typedef void (*jni_array_setter) (JNIEnv *, jarray, jsize, jvalue);
66 typedef jlong (*jni_array_referrer) (JNIEnv *, jarray, jsize);
68 struct jni_primitive_wrapper {
69 jni_method_caller call_method;
70 jni_static_method_caller call_static_method;
71 jni_nonvirtual_method_caller call_nonvirtual_method;
72 jni_array_allocater new_array;
73 jni_array_setter set_array_element;
74 jni_array_referrer get_array_element;
77 typedef jboolean (*java_modifier_filter)(JNIEnv *, jint);
79 struct java_class_list_closure
81 Lisp_Object *java_class_list;
84 static struct jni_primitive_wrapper jni_primitive_call_table[8];
85 static const Extbyte *jni_primitive_signature_table = "ZBCSIJFD";
87 inline static jvalue jni_primitive_call_method
88 (JNIEnv *, const Extbyte *, jobject, jmethodID, jvalue *);
89 inline static jvalue jni_primitive_call_static_method
90 (JNIEnv *, const Extbyte *, jclass, jmethodID, jvalue *);
91 inline static jarray jni_primitive_new_array
92 (JNIEnv *, const Extbyte *, jsize);
93 inline static void jni_primitive_set_array_element
94 (JNIEnv *, const Extbyte *, jarray, jsize, jvalue);
95 inline static jvalue jni_primitive_get_array_element
96 (JNIEnv *, const Extbyte *, jarray, jsize);
98 static void jni_initialize_primitive_call_table (JNIEnv *);
99 static int jni_lookup_primitive_call_table (const char *);
100 static jobjectArray jni_class_get_methods (JNIEnv *, jclass);
101 static jobjectArray jni_class_get_constructors (JNIEnv *, jclass);
102 static jstring jni_class_get_name (JNIEnv *, jclass class);
103 static jboolean jni_class_is_primitive (JNIEnv *, jclass);
104 static jobjectArray jni_method_get_parameter_types (JNIEnv *, jobject);
105 static jstring jni_method_get_name (JNIEnv *, jobject);
106 static jint jni_method_get_modifiers (JNIEnv *, jobject);
107 static jclass jni_method_get_return_type (JNIEnv *, jobject);
108 static jboolean jni_modifier_is_static (JNIEnv *, jint);
109 static jboolean jni_modifier_is_non_static (JNIEnv *, jint);
110 static void jni_check_exception (JNIEnv *);
111 static jvalue jni_call_static_method (JNIEnv *, const Extbyte *,
112 jclass, jmethodID, jvalue *);
113 static jvalue jni_call_virtual_method (JNIEnv *, const Extbyte *,
114 jobject, jmethodID, jvalue *);
116 static Lisp_Object Vjava_class_hash_table;
119 initialize_javavm (void)
121 JavaVMInitArgs vm_args;
122 JavaVMOption options[2];
123 jint noptions = 0, status;
125 options[0].optionString = "abort";
126 options[0].extraInfo = abort;
128 if (!NILP (Vjava_class_path))
130 CHECK_STRING (Vjava_class_path);
132 options[noptions++].optionString =
133 java_build_property_string (build_string ("java.class.path"),
137 vm_args.version = JNI_VERSION_1_2;
138 vm_args.options = options;
139 vm_args.nOptions = noptions;
140 vm_args.ignoreUnrecognized = JNI_TRUE;
142 status = JNI_CreateJavaVM (&java_jvm, (void **)&java_env, &vm_args);
144 error ("Can't create Java VM. Error: %ld\n", status);
146 jni_initialize_primitive_call_table (java_env);
150 finalize_javavm (void)
152 (*java_jvm)->DestroyJavaVM (java_jvm);
158 make_javaclass (Lisp_JavaClass *javaclass)
160 Lisp_Object lisp_javaclass;
161 XSETJAVACLASS (lisp_javaclass, javaclass);
162 return lisp_javaclass;
166 mark_javaclass (Lisp_Object obj)
168 Lisp_JavaClass *javaclass = XJAVACLASS (obj);
169 return javaclass->name;
173 print_javaclass (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
175 Lisp_JavaClass *javaclass;
178 javaclass = XJAVACLASS (obj);
180 if (NILP (javaclass->name))
181 strcpy (buf, "#<javaclass>");
183 sprintf (buf, "#<javaclass \"%s\">", XSTRING_DATA (javaclass->name));
184 write_c_string (buf, printcharfun);
187 static Lisp_JavaClass *
188 allocate_javaclass (void)
190 Lisp_JavaClass *javaclass = alloc_lcrecord_type (Lisp_JavaClass,
193 javaclass->class = (jclass)NULL;
194 javaclass->name = Qnil;
198 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION ("javaclass", javaclass,
199 mark_javaclass, print_javaclass, NULL,
205 make_javaobject (Lisp_JavaObject *javaobject)
207 Lisp_Object lisp_javaobject;
208 XSETJAVAOBJECT (lisp_javaobject, javaobject);
209 return lisp_javaobject;
213 mark_javaobject (Lisp_Object obj)
215 Lisp_JavaObject *javaobject = XJAVAOBJECT (obj);
216 return javaobject->signature;
220 print_javaobject (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
222 Lisp_JavaObject *javaobject;
225 javaobject = XJAVAOBJECT (obj);
227 if (NILP (javaobject->signature))
228 strcpy (buf, "#<javaobject>");
230 sprintf (buf, "#<javaobject \"%s\">",
231 XSTRING_DATA (javaobject->signature));
232 write_c_string (buf, printcharfun);
235 static Lisp_JavaObject *
236 allocate_javaobject (void)
238 Lisp_JavaObject *javaobject;
240 javaobject = alloc_lcrecord_type (Lisp_JavaObject, &lrecord_javaobject);
241 javaobject->object = (jobject)NULL;
242 javaobject->signature = Qnil;
246 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION ("javaobject", javaobject,
247 mark_javaobject, print_javaobject,
252 DEFUN ("java-initialize", Fjava_initialize, 0, 0, 0, /*
253 Initialize the Java Virtual Machine.
257 if (JAVAVM_LIVE_P ())
260 initialize_javavm ();
261 if (JAVAVM_LIVE_P ())
264 return Qnil; /* not reached */
267 DEFUN ("java-finalize", Fjava_finalize, 0, 0, 0, /*
268 Finalize the Java Virtual Machine.
272 CHECK_LIVE_JAVAVM ();
278 DEFUN ("java-find-class", Fjava_find_class, 1, 1, 0, /*
285 Lisp_JavaClass *javaclass;
288 CHECK_LIVE_JAVAVM ();
291 class = Fgethash (name, Vjava_class_hash_table, Qnil);
292 if (JAVACLASSP (class))
295 TO_EXTERNAL_FORMAT (LISP_STRING, name, C_STRING_ALLOCA, c_name, Qnative);
296 java_dots_to_slashes (c_name);
297 clazz = (*java_env)->FindClass (java_env, c_name);
299 error ("Can't locate the %s class", XSTRING_DATA (name));
301 javaclass = allocate_javaclass ();
302 javaclass->class = clazz;
303 javaclass->name = name;
305 class = make_javaclass (javaclass);
306 Fputhash (javaclass->name, class, Vjava_class_hash_table);
311 java_build_property_string (name, value)
312 Lisp_Object name, value;
314 const Extbyte *c_name, *c_value;
317 TO_EXTERNAL_FORMAT (LISP_STRING, name, C_STRING_ALLOCA, c_name, Qnative);
318 TO_EXTERNAL_FORMAT (LISP_STRING, value, C_STRING_ALLOCA, c_value, Qnative);
320 c_property = xmalloc (strlen (c_name) + strlen (c_value) + 4);
321 sprintf (c_property, "-D%s=%s", c_name, c_value);
327 java_dots_to_slashes (c_class)
332 for (end = c_class + strlen (c_class); c_class < end; c_class++)
337 inline static Extbyte *
338 java_primitive_type_signature (name)
341 if (!strncmp (name, "boolean", 7))
343 else if (!strncmp (name, "byte", 4))
345 else if (!strncmp (name, "char", 4))
347 else if (!strncmp (name, "short", 5))
349 else if (!strncmp (name, "int", 3))
351 else if (!strncmp (name, "long", 4))
353 else if (!strncmp (name, "float", 5))
355 else if (!strncmp (name, "double", 6))
357 else if (!strncmp (name, "void", 4))
361 static const Extbyte *
362 java_type_signature (env, class)
366 jstring string = jni_class_get_name (env, class);
367 const Extbyte *utf_string, *signature;
371 utf_string = (*env)->GetStringUTFChars (env, string, &is_copy);
373 if (jni_class_is_primitive (env, class))
374 signature = java_primitive_type_signature (utf_string);
375 else if (utf_string[0] == '[')
377 signature = buf = xstrdup (utf_string);
378 java_dots_to_slashes (buf);
382 signature = buf = xmalloc (strlen (utf_string) + 3);
383 sprintf (buf, "L%s;", utf_string);
384 java_dots_to_slashes (buf);
386 if (is_copy == JNI_TRUE)
387 (*env)->ReleaseStringUTFChars (env, string, utf_string);
393 java_unify_primitive_array (env, element_sig, obj)
395 const Extbyte *element_sig;
398 int i, index, len = XVECTOR_LENGTH (obj);
399 Lisp_Object *data = XVECTOR_DATA (obj);
402 array = jni_primitive_new_array (env, element_sig, len);
404 for (i = 0; i<len; i++)
407 if (!java_unify_parameter (env, element_sig, data[i], ¶m))
409 jni_primitive_set_array_element (env, element_sig, array, i, param);
415 java_unify_object_array (env, element_sig, obj)
417 const Extbyte *element_sig;
420 int i, index, len = XVECTOR_LENGTH (obj);
421 Lisp_Object *data = XVECTOR_DATA (obj);
423 int element_sig_len = strlen (element_sig);
424 Extbyte *name = xstrdup (element_sig + 1);
427 name[element_sig_len - 2] = '\0'; /* remove the last ";" */
428 class = Fjava_find_class (build_string (name));
429 array = (*env)->NewObjectArray (env, len, XJAVACLASS (class)->class, NULL);
432 name = alloca (element_sig_len + 1);
433 strncpy (name, element_sig, element_sig_len);
434 name[element_sig_len] = '\0';
435 for (i = 0; i<len; i++)
438 if (!java_unify_parameter (env, name, data[i], ¶m))
440 (*env)->SetObjectArrayElement (env, array, i, param.l);
445 /* Convert a Lisp object into a Java object according to PARAM_SIG. */
447 java_unify_parameter (env, param_sig, obj, param)
449 const Extbyte *param_sig;
453 switch (param_sig[0])
456 param->z = NILP (obj) ? JNI_FALSE : JNI_TRUE;
461 param->b = (jshort) XINT (obj);
466 obj = Fchar_ucs (obj);
469 param->c = (jchar) XINT (obj);
475 param->s = (jshort) XINT (obj);
480 param->i = (jint) XINT (obj);
485 param->j = (jlong) XINT (obj);
488 if (!INT_OR_FLOATP (obj))
490 param->f = (jfloat) XFLOATINT (obj);
493 if (!INT_OR_FLOATP (obj))
495 param->d = (jdouble) XFLOATINT (obj);
498 if (!JAVAOBJECTP (obj) && !STRINGP (obj)
499 || strncmp (param_sig, "Ljava/lang/String;", 18))
501 if (JAVAOBJECTP (obj))
502 param->l = XJAVAOBJECT (obj)->object;
503 else if (STRINGP (obj))
505 const Extbyte *c_string;
506 TO_EXTERNAL_FORMAT (LISP_STRING, obj, C_STRING_ALLOCA,
508 param->l = (jobject) (*env)->NewStringUTF (env, c_string);
512 if (!VECTORP (obj) && !BIT_VECTORP (obj)
513 || !strncmp (param_sig, "[Z", 2))
515 if (BIT_VECTORP (obj))
516 obj = vconcat2 (obj, Qnil);
517 if (param_sig[1] == 'L')
518 param->l = java_unify_object_array (env, param_sig+1, obj);
520 param->l = java_unify_primitive_array (env, param_sig+1, obj);
528 static const Extbyte *
529 java_unify_parameters (env, ptypes, nargs, args, params)
536 int i, bufsize = 128, nptypes = (*env)->GetArrayLength (env, ptypes);
537 char *p, *buf = xmalloc_and_zero (bufsize);
539 for (p = buf, i = 0; i < nptypes; i++)
541 jclass element = (*env)->GetObjectArrayElement (env, ptypes, i);
542 const Extbyte *param_sig = java_type_signature (env, element);
543 int len = strlen (param_sig);
544 (*env)->DeleteLocalRef (env, element);
545 if (!java_unify_parameter (env, param_sig, args[i], ¶ms[i]))
551 while ((buf - p) + len > bufsize)
554 buf = xrealloc (buf, bufsize);
557 strncpy (buf, param_sig, len);
563 java_build_return_value_vector (env, return_sig, array)
565 const Extbyte *return_sig;
568 jint len = (*env)->GetArrayLength (env, array);
569 Lisp_Object v = make_vector (len, Qnil);
571 Extbyte *name = xstrdup (return_sig);
574 if (name[0] == 'L' || name[0] == '[')
575 for (i = 0; i<len; i++)
577 element.l = (*env)->GetObjectArrayElement (env, array, i);
578 Faset (v, make_int (i), java_build_return_value (env, name, element));
581 for (i = 0; i<len; i++)
583 element = jni_primitive_get_array_element (env, name, array, i);
584 Faset (v, make_int (i), java_build_return_value (env, name, element));
590 /* Convert a Java object into a Lisp object according to RETURN_SIG. */
592 java_build_return_value (env, return_sig, value)
594 const Extbyte *return_sig;
597 switch (return_sig[0])
600 return value.z ? Qt : Qnil;
602 return make_int (value.b);
605 Lisp_Object ucs = make_int (value.c);
606 return Fucs_char (ucs);
609 return make_int (value.s);
611 return make_int (value.i);
613 return make_int (value.j);
615 return make_float (value.f);
617 return make_float (value.d);
619 if (!strncmp (return_sig, "Ljava/lang/String;", 18))
621 const Extbyte *utf_string;
627 utf_string = (*env)->GetStringUTFChars (env, value.l, &is_copy);
628 string = build_ext_string (utf_string, JAVA_OS_CODING);
629 if (is_copy == JNI_TRUE)
630 (*env)->ReleaseStringUTFChars (env, value.l, utf_string);
635 Lisp_JavaObject *javaobject;
637 javaobject = allocate_javaobject ();
638 javaobject->object = value.l;
639 javaobject->signature = build_string (return_sig);
641 return make_javaobject (javaobject);
645 return java_build_return_value_vector (env, return_sig+1, value.l);
648 error ("Can't cast the return value.");
654 java_find_method (env, methods, c_method_to_invoke,
655 nargs, args, params, filter)
657 jobjectArray methods;
658 const Extbyte *c_method_to_invoke;
662 java_modifier_filter filter;
664 jobject method = NULL;
668 nmethods = (*env)->GetArrayLength (env, methods);
669 for (i = 0; i < nmethods; i++)
672 (*env)->GetObjectArrayElement (env, methods, i);
673 jint modifiers = jni_method_get_modifiers (env, element);
676 jstring name = jni_method_get_name (env, element);
677 const Extbyte *utf_name, *param_sig;
680 utf_name = (*java_env)->GetStringUTFChars (env, name, &is_copy);
682 if (c_method_to_invoke && strcmp (utf_name, c_method_to_invoke))
684 if (filter && (*filter) (env, modifiers) != JNI_TRUE)
687 ptypes = jni_method_get_parameter_types (env, element);
688 nptypes = (*env)->GetArrayLength (env, ptypes);
690 if (nptypes != nargs)
693 param_sig = java_unify_parameters (env, ptypes, nargs, args, params);
701 if (is_copy == JNI_TRUE)
702 (*env)->ReleaseStringUTFChars (env, name, utf_name);
703 (*env)->DeleteLocalRef (env, element);
709 java_call_static_method (obj, name, nargs, args)
710 Lisp_Object obj, name, *args;
713 jclass class, return_type;
714 jobjectArray methods;
716 jvalue *params, value;
719 const Extbyte *return_sig;
720 java_modifier_filter filter;
722 /* Prepare for the static method call. */
723 class = XJAVACLASS (obj)->class;
724 filter = jni_modifier_is_static;
725 params = alloca (sizeof (jvalue) * nargs);
727 /* Do unification in the ordinary way.
728 This part can be commonly used and should be split off. */
729 methods = jni_class_get_methods (java_env, class);
730 TO_EXTERNAL_FORMAT(LISP_STRING, name, C_STRING_ALLOCA, c_name, Qnative);
731 method = java_find_method (java_env, methods, c_name, nargs, args, params,
734 error ("Bad method name: %s", XSTRING_DATA (name));
736 method_id = (*java_env)->FromReflectedMethod (java_env, method);
737 return_type = jni_method_get_return_type (java_env, method);
738 return_sig = java_type_signature (java_env, return_type);
739 (*java_env)->DeleteLocalRef (java_env, method);
741 value = jni_call_static_method (java_env, return_sig, class, method_id,
744 /* Clean up returned value.
745 This part can be commonly used and should be split off. */
746 jni_check_exception (java_env);
747 if (!value.l) /* possibly null or void */
749 return java_build_return_value (java_env, return_sig, value);
753 java_call_virtual_method (obj, name, nargs, args)
754 Lisp_Object obj, name, *args;
757 jclass class, return_type;
758 jobjectArray methods;
759 jobject object, method;
760 jvalue *params, value;
763 const Extbyte *return_sig;
764 java_modifier_filter filter;
766 /* Prepare for the virtual method call. */
767 object = XJAVAOBJECT (obj)->object;
768 class = (*java_env)->GetObjectClass (java_env, object);
769 filter = jni_modifier_is_non_static;
770 params = alloca (sizeof (jvalue) * nargs);
773 This part can be commonly used and should be split off. */
774 methods = jni_class_get_methods (java_env, class);
775 TO_EXTERNAL_FORMAT(LISP_STRING, name, C_STRING_ALLOCA, c_name, Qnative);
776 method = java_find_method (java_env, methods, c_name, nargs, args, params,
779 error ("Bad method name: %s", XSTRING_DATA (name));
781 method_id = (*java_env)->FromReflectedMethod (java_env, method);
782 return_type = jni_method_get_return_type (java_env, method);
783 return_sig = java_type_signature (java_env, return_type);
784 (*java_env)->DeleteLocalRef (java_env, method);
786 value = jni_call_virtual_method (java_env, return_sig, object, method_id,
789 /* Clean up returned value.
790 This part can be commonly used and should be split off. */
791 jni_check_exception (java_env);
792 if (!value.l) /* possibly null or void */
794 return java_build_return_value (java_env, return_sig, value);
797 DEFUN ("java-call-static-method", Fjava_call_static_method, 2, MANY, 0, /*
800 (int nargs, Lisp_Object *args))
802 Lisp_Object class = args[0];
803 Lisp_Object method = args[1];
804 java_modifier_filter filter;
806 CHECK_JAVACLASS (class);
807 CHECK_STRING (method);
808 CHECK_LIVE_JAVAVM ();
810 return java_call_static_method (class, method, nargs - 2, args + 2);
813 DEFUN ("java-call-virtual-method", Fjava_call_virtual_method, 2, MANY, 0, /*
816 (int nargs, Lisp_Object *args))
818 Lisp_Object object = args[0];
819 Lisp_Object method = args[1];
821 CHECK_JAVAOBJECT (object);
822 CHECK_STRING (method);
823 CHECK_LIVE_JAVAVM ();
825 return java_call_virtual_method (object, method, nargs - 2, args + 2);
829 java_make_object (class, nargs, args)
830 Lisp_Object class, *args;
834 jobjectArray constructors;
835 jobject constructor, object;
838 int i, nconstructors;
839 const Extbyte *param_sig;
840 Lisp_JavaObject *javaobject;
842 clazz = XJAVACLASS (class)->class;
843 constructors = jni_class_get_constructors (java_env, clazz);
844 nconstructors = (*java_env)->GetArrayLength (java_env, constructors);
845 params = alloca (sizeof (jvalue) * nargs);
847 constructor = java_find_method (java_env, constructors, NULL,
848 nargs, args, params, NULL);
851 error ("No such constructor: %s\n",
852 XSTRING_DATA (XJAVACLASS (class)->name));
854 method_id = (*java_env)->FromReflectedMethod (java_env, constructor);
855 object = (*java_env)->NewObjectA (java_env, clazz, method_id, params);
860 javaobject = allocate_javaobject ();
861 javaobject->object = object;
862 javaobject->signature = XJAVACLASS (class)->name;
864 return make_javaobject (javaobject);
867 DEFUN ("java-make-object", Fjava_make_object, 1, MANY, 0, /*
870 (int nargs, Lisp_Object *args))
872 Lisp_Object class = args[0];
874 CHECK_JAVACLASS (class);
875 CHECK_LIVE_JAVAVM ();
877 return java_make_object (class, nargs - 1, args + 1);
881 add_java_class_to_list_mapper (Lisp_Object key, Lisp_Object value,
882 void *java_class_list_closure)
884 /* This function can GC */
885 struct java_class_list_closure *cscl =
886 (struct java_class_list_closure *) java_class_list_closure;
887 Lisp_Object *java_class_list = cscl->java_class_list;
889 *java_class_list = Fcons (value, *java_class_list);
893 DEFUN ("java-class-list", Fjava_class_list, 0, 0, 0, /*
894 Return a list of all loaded classes.
898 Lisp_Object java_class_list = Qnil;
900 struct java_class_list_closure java_class_list_closure;
902 GCPRO1 (java_class_list);
903 java_class_list_closure.java_class_list = &java_class_list;
904 elisp_maphash (add_java_class_to_list_mapper, Vjava_class_hash_table,
905 &java_class_list_closure);
908 return java_class_list;
911 DEFUN ("java-class-name", Fjava_class_name, 1, 1, 0, /*
912 Return the name of the given class.
916 CHECK_JAVACLASS (class);
917 return XJAVACLASS (class)->name;
921 jni_lookup_primitive_call_table (signature)
922 const char *signature;
924 const char *p = strchr (jni_primitive_signature_table, signature[0]);
927 return (p - jni_primitive_signature_table);
931 jni_primitive_call_method (env, return_sig, object, method, params)
933 const Extbyte *return_sig;
938 int index = jni_lookup_primitive_call_table (return_sig);
939 return (jvalue)(*jni_primitive_call_table[index].call_method)
940 (env, object, method, params);
944 jni_primitive_call_static_method (env, return_sig, class, method, params)
946 const Extbyte *return_sig;
951 int index = jni_lookup_primitive_call_table (return_sig);
952 return (jvalue)(*jni_primitive_call_table[index].call_static_method)
953 (env, class, method, params);
957 jni_primitive_new_array (env, element_sig, len)
959 const Extbyte *element_sig;
962 int index = jni_lookup_primitive_call_table (element_sig);
963 return (*jni_primitive_call_table[index].new_array)
968 jni_primitive_set_array_element (env, element_sig, array, n, element)
970 const Extbyte *element_sig;
975 int index = jni_lookup_primitive_call_table (element_sig);
976 jni_primitive_call_table[index].set_array_element
977 (env, array, n, element);
981 jni_primitive_get_array_element (env, element_sig, array, n)
983 const Extbyte *element_sig;
987 int index = jni_lookup_primitive_call_table (element_sig);
988 return (jvalue)(*jni_primitive_call_table[index].get_array_element)
992 #define DEFINE_JNI_ARRAY_SET(atype,jtype,type) \
993 static void jni_set_##jtype##_array_element (JNIEnv *, jarray, \
995 static void jni_set_##jtype##_array_element (JNIEnv *env, jarray array, \
996 jsize n, jvalue element) { \
999 elements = (*env)->Get##type##ArrayElements (env, (atype)array, \
1001 elements[n] = *(jtype*)&element; \
1002 if (is_copy == JNI_TRUE) \
1003 (*env)->Release##type##ArrayElements \
1004 (env, (atype)array, elements, 0); \
1007 DEFINE_JNI_ARRAY_SET(jbooleanArray, jboolean, Boolean)
1008 DEFINE_JNI_ARRAY_SET(jbyteArray, jbyte, Byte)
1009 DEFINE_JNI_ARRAY_SET(jcharArray, jchar, Char)
1010 DEFINE_JNI_ARRAY_SET(jshortArray, jshort, Short)
1011 DEFINE_JNI_ARRAY_SET(jintArray, jint, Int)
1012 DEFINE_JNI_ARRAY_SET(jlongArray, jlong, Long)
1013 DEFINE_JNI_ARRAY_SET(jfloatArray, jfloat, Float)
1014 DEFINE_JNI_ARRAY_SET(jdoubleArray, jdouble, Double)
1016 #define DEFINE_JNI_ARRAY_GET(atype,jtype,type) \
1017 static jlong jni_get_##jtype##_array_element (JNIEnv *, jarray, jsize); \
1018 static jlong jni_get_##jtype##_array_element (JNIEnv *env, \
1019 jarray array, jsize n) { \
1022 elements = (*env)->Get##type##ArrayElements (env, (atype)array, \
1024 return (jlong)elements[n]; \
1027 DEFINE_JNI_ARRAY_GET(jbooleanArray, jboolean, Boolean)
1028 DEFINE_JNI_ARRAY_GET(jbyteArray, jbyte, Byte)
1029 DEFINE_JNI_ARRAY_GET(jcharArray, jchar, Char)
1030 DEFINE_JNI_ARRAY_GET(jshortArray, jshort, Short)
1031 DEFINE_JNI_ARRAY_GET(jintArray, jint, Int)
1032 DEFINE_JNI_ARRAY_GET(jlongArray, jlong, Long)
1033 DEFINE_JNI_ARRAY_GET(jfloatArray, jfloat, Float)
1034 DEFINE_JNI_ARRAY_GET(jdoubleArray, jdouble, Double)
1037 jni_initialize_primitive_call_table (env)
1040 jni_primitive_call_table[0].call_method =
1041 (jni_method_caller)(*env)->CallBooleanMethodA;
1042 jni_primitive_call_table[0].call_static_method =
1043 (jni_static_method_caller)(*env)->CallStaticBooleanMethodA;
1044 jni_primitive_call_table[0].call_nonvirtual_method =
1045 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualBooleanMethodA;
1046 jni_primitive_call_table[0].new_array =
1047 (jni_array_allocater)(*env)->NewBooleanArray;
1048 jni_primitive_call_table[0].set_array_element =
1049 jni_set_jboolean_array_element;
1050 jni_primitive_call_table[0].get_array_element =
1051 jni_get_jboolean_array_element;
1053 jni_primitive_call_table[1].call_method =
1054 (jni_method_caller)(*env)->CallByteMethodA;
1055 jni_primitive_call_table[1].call_static_method =
1056 (jni_static_method_caller)(*env)->CallStaticByteMethodA;
1057 jni_primitive_call_table[1].call_nonvirtual_method =
1058 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualByteMethodA;
1059 jni_primitive_call_table[1].new_array =
1060 (jni_array_allocater)(*env)->NewByteArray;
1061 jni_primitive_call_table[1].set_array_element =
1062 jni_set_jbyte_array_element;
1063 jni_primitive_call_table[1].get_array_element =
1064 jni_get_jbyte_array_element;
1066 jni_primitive_call_table[2].call_method =
1067 (jni_method_caller)(*env)->CallCharMethodA;
1068 jni_primitive_call_table[2].call_static_method =
1069 (jni_static_method_caller)(*env)->CallStaticCharMethodA;
1070 jni_primitive_call_table[2].call_nonvirtual_method =
1071 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualCharMethodA;
1072 jni_primitive_call_table[2].new_array =
1073 (jni_array_allocater)(*env)->NewCharArray;
1074 jni_primitive_call_table[2].set_array_element =
1075 jni_set_jchar_array_element;
1076 jni_primitive_call_table[2].get_array_element =
1077 jni_get_jchar_array_element;
1079 jni_primitive_call_table[3].call_method =
1080 (jni_method_caller)(*env)->CallShortMethodA;
1081 jni_primitive_call_table[3].call_static_method =
1082 (jni_static_method_caller)(*env)->CallStaticShortMethodA;
1083 jni_primitive_call_table[3].call_nonvirtual_method =
1084 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualShortMethodA;
1085 jni_primitive_call_table[3].new_array =
1086 (jni_array_allocater)(*env)->NewShortArray;
1087 jni_primitive_call_table[3].set_array_element =
1088 jni_set_jshort_array_element;
1089 jni_primitive_call_table[3].get_array_element =
1090 jni_get_jshort_array_element;
1092 jni_primitive_call_table[4].call_method =
1093 (jni_method_caller)(*env)->CallIntMethodA;
1094 jni_primitive_call_table[4].call_static_method =
1095 (jni_static_method_caller)(*env)->CallStaticIntMethodA;
1096 jni_primitive_call_table[4].call_nonvirtual_method =
1097 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualIntMethodA;
1098 jni_primitive_call_table[4].new_array =
1099 (jni_array_allocater)(*env)->NewIntArray;
1100 jni_primitive_call_table[4].set_array_element =
1101 jni_set_jint_array_element;
1102 jni_primitive_call_table[4].get_array_element =
1103 jni_get_jint_array_element;
1105 jni_primitive_call_table[5].call_method =
1106 (jni_method_caller)(*env)->CallLongMethodA;
1107 jni_primitive_call_table[5].call_static_method =
1108 (jni_static_method_caller)(*env)->CallStaticLongMethodA;
1109 jni_primitive_call_table[5].call_nonvirtual_method =
1110 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualLongMethodA;
1111 jni_primitive_call_table[5].new_array =
1112 (jni_array_allocater)(*env)->NewLongArray;
1113 jni_primitive_call_table[5].set_array_element =
1114 jni_set_jlong_array_element;
1115 jni_primitive_call_table[5].get_array_element =
1116 jni_get_jlong_array_element;
1118 jni_primitive_call_table[6].call_method =
1119 (jni_method_caller)(*env)->CallFloatMethodA;
1120 jni_primitive_call_table[6].call_static_method =
1121 (jni_static_method_caller)(*env)->CallStaticFloatMethodA;
1122 jni_primitive_call_table[6].call_nonvirtual_method =
1123 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualFloatMethodA;
1124 jni_primitive_call_table[6].new_array =
1125 (jni_array_allocater)(*env)->NewFloatArray;
1126 jni_primitive_call_table[6].set_array_element =
1127 jni_set_jfloat_array_element;
1128 jni_primitive_call_table[6].get_array_element =
1129 jni_get_jfloat_array_element;
1131 jni_primitive_call_table[7].call_method =
1132 (jni_method_caller)(*env)->CallDoubleMethodA;
1133 jni_primitive_call_table[7].call_static_method =
1134 (jni_static_method_caller)(*env)->CallStaticDoubleMethodA;
1135 jni_primitive_call_table[7].call_nonvirtual_method =
1136 (jni_nonvirtual_method_caller)(*env)->CallNonvirtualDoubleMethodA;
1137 jni_primitive_call_table[7].new_array =
1138 (jni_array_allocater)(*env)->NewDoubleArray;
1139 jni_primitive_call_table[7].set_array_element =
1140 jni_set_jdouble_array_element;
1141 jni_primitive_call_table[7].get_array_element =
1142 jni_get_jdouble_array_element;
1146 jni_class_get_methods (env, class)
1150 jclass clazz = (*env)->GetObjectClass (env, class);
1151 jmethodID method = (*env)->GetMethodID (env, clazz, "getMethods",
1152 "()[Ljava/lang/reflect/Method;");
1153 return (jobjectArray) (*env)->CallObjectMethod (env, class, method, NULL);
1157 jni_class_get_constructors (env, class)
1161 jclass clazz = (*env)->GetObjectClass (env, class);
1162 jmethodID method = (*env)->GetMethodID (env, clazz, "getConstructors",
1163 "()[Ljava/lang/reflect/Constructor;");
1164 return (jobjectArray) (*env)->CallObjectMethod (env, class, method, NULL);
1168 jni_class_get_name (env, class)
1172 jclass clazz = (*env)->GetObjectClass (env, class);
1173 jmethodID method = (*env)->GetMethodID (env, clazz, "getName",
1174 "()Ljava/lang/String;");
1175 return (jstring) (*env)->CallObjectMethod (env, class, method, NULL);
1179 jni_class_is_primitive (env, class)
1183 jclass clazz = (*env)->GetObjectClass (env, class);
1184 jmethodID method = (*env)->GetMethodID (env, clazz, "isPrimitive",
1186 return (*env)->CallBooleanMethod (env, class, method, NULL);
1190 jni_method_get_parameter_types (env, method)
1194 jclass class = (*env)->GetObjectClass (env, method);
1195 jmethodID get_parameter_types =
1196 (*env)->GetMethodID (env, class, "getParameterTypes",
1197 "()[Ljava/lang/Class;");
1198 return (jobjectArray) (*env)->CallObjectMethod
1199 (env, method, get_parameter_types, NULL);
1203 jni_method_get_name (env, method)
1207 jclass class = (*env)->GetObjectClass (env, method);
1208 jmethodID get_name =
1209 (*env)->GetMethodID (env, class, "getName", "()Ljava/lang/String;");
1210 return (jstring) (*env)->CallObjectMethod (env, method, get_name, NULL);
1214 jni_method_get_modifiers (env, method)
1218 jclass class = (*env)->GetObjectClass (env, method);
1219 jmethodID get_modifiers =
1220 (*env)->GetMethodID (env, class, "getModifiers", "()I");
1221 return (*env)->CallIntMethod (env, method, get_modifiers, NULL);
1225 jni_method_get_return_type (env, method)
1229 jclass class = (*env)->GetObjectClass (env, method);
1230 jmethodID get_return_type =
1231 (*env)->GetMethodID (env, class, "getReturnType", "()Ljava/lang/Class;");
1232 return (jclass) (*env)->CallObjectMethod
1233 (env, method, get_return_type, NULL);
1237 jni_modifier_is_static (env, modifiers)
1241 static jclass class = NULL;
1242 jmethodID is_static;
1245 class = (*env)->FindClass (env, "java/lang/reflect/Modifier");
1246 is_static = (*env)->GetStaticMethodID (env, class, "isStatic", "(I)Z");
1247 return (*env)->CallStaticBooleanMethod (env, class, is_static, modifiers);
1251 jni_modifier_is_non_static (env, modifiers)
1255 if (jni_modifier_is_static (env, modifiers) == JNI_TRUE)
1261 jni_check_exception (env)
1264 jthrowable throwable;
1266 throwable = (*env)->ExceptionOccurred (env);
1270 (*env)->ExceptionClear (env);
1271 error ("Exception occurred.");
1275 jni_call_static_method (env, return_sig, class, method, params)
1277 const Extbyte *return_sig;
1282 jthrowable throwable;
1285 switch (return_sig[0])
1288 (*env)->CallStaticVoidMethodA (env, class, method, params);
1291 value = (jvalue)(*env)->CallStaticObjectMethodA
1292 (env, class, method, params);
1295 value = jni_primitive_call_static_method (env, return_sig, class,
1304 jni_call_virtual_method (env, return_sig, object, method, params)
1306 const Extbyte *return_sig;
1311 jthrowable throwable;
1314 switch (return_sig[0])
1317 (*env)->CallVoidMethodA (env, object, method, params);
1320 value = (jvalue)(*env)->CallObjectMethodA (env, object, method, params);
1323 value = jni_primitive_call_method (env, return_sig, object, method,
1335 INIT_EXTERNAL_LRECORD_IMPLEMENTATION (javaclass);
1336 INIT_EXTERNAL_LRECORD_IMPLEMENTATION (javaobject);
1337 defsymbol (&Qjava, "java");
1339 defsymbol (&Qjavaclassp, "javaclassp");
1340 defsymbol (&Qjavaobjectp, "javaobjectp");
1342 DEFSUBR (Fjava_find_class);
1343 DEFSUBR (Fjava_call_virtual_method);
1344 DEFSUBR (Fjava_call_static_method);
1345 DEFSUBR (Fjava_make_object);
1346 DEFSUBR (Fjava_class_list);
1347 DEFSUBR (Fjava_class_name);
1357 DEFVAR_LISP ("java-coding-system", &Vjava_coding_system /*
1358 Default Java Vartual Machine coding system.
1360 Vjava_coding_system = Qnative;
1362 DEFVAR_LISP ("java-class-path", &Vjava_class_path /*
1365 p = getenv ("CLASSPATH");
1367 Vjava_class_path = Qnil;
1369 Vjava_class_path = build_ext_string (p, JAVA_OS_CODING);
1371 initialize_javavm ();
1373 staticpro (&Vjava_class_hash_table);
1374 Vjava_class_hash_table =
1375 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);