JNI/Win32 Patch #4: Make "stdcall"-based JNI method calls possible for compiled code

Ranjit Mathew rmathew@hotmail.com
Sun Dec 8 09:20:00 GMT 2002


Hi,

     This patch proposes to change the stubs generated by the Java
front-end to call Java Native Interface (JNI) methods, so that it
works on the Win32 targets (MinGW and Cygwin).

The chain of reasoning behind this change can be found in the
threads started by these messages:

     http://gcc.gnu.org/ml/java/2002-11/msg00152.html
     http://gcc.gnu.org/ml/java/2002-11/msg00257.html

Please note that this patch assumes that the following patch
has been applied to libjava (for _Jv_LookupJNIMethod( )):

     http://gcc.gnu.org/ml/java-patches/2002-q4/msg00390.html

Finally, I've used the MODIFY_JNI_METHOD_CALL target macro
as proposed in this message I sent to the gcc mailing list:

     http://gcc.gnu.org/ml/gcc/2002-12/msg00255.html

I received neither positive nor negative feedback (:-() about
that proposal, so I assume that it is not *that gross* as
perceived by the GCC/GCJ developers - otherwise I think I
would have received howls of protest by now. ;-)


ChangeLog:

2002-12-08  Ranjit Mathew  <rmathew@hotmail.com>

	* decl.c (java_init_decl_processing): Change
	soft_lookupjnimethod_node to reflect the change in signature
	of _Jv_LookupJNIMethod( ) in libjava/jni.cc.

	* expr.c (build_jni_stub): Calculate and pass the size
	on the stack of the arguments to a JNI function. Use new
	target macro MODIFY_JNI_METHOD_CALL to allow a target to
	modify the call to a JNI method.

-------------------------------- 8< --------------------------------
--- decl.c	2002-11-11 03:02:05.000000000 +0530
+++ decl.c	2002-12-04 23:20:40.000000000 +0530
@@ -881,5 +881,7 @@
    t = tree_cons (NULL_TREE, object_ptr_type_node,
  		 tree_cons (NULL_TREE, ptr_type_node,
-			    tree_cons (NULL_TREE, ptr_type_node, endlink)));
+			    tree_cons (NULL_TREE, ptr_type_node,
+			               tree_cons (NULL_TREE, int_type_node,
+				                  endlink))));
    soft_lookupjnimethod_node
      = builtin_function ("_Jv_LookupJNIMethod",
--- expr.c	2002-11-11 03:02:00.000000000 +0530
+++ expr.c	2002-12-08 20:40:35.000000000 +0530
@@ -2174,4 +2174,6 @@
    tree meth_var;

+  int args_size = 0;
+
    tree klass = DECL_CONTEXT (method);
    int from_class = ! CLASS_FROM_SOURCE_P (klass);
@@ -2235,5 +2237,14 @@
    args = NULL_TREE;
    for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
-    args = tree_cons (NULL_TREE, tem, args);
+    {
+      int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
+#ifdef PARM_BOUNDARY
+      arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY) *
+                  PARM_BOUNDARY);
+#endif
+      args_size += (arg_bits / BITS_PER_UNIT);
+
+      args = tree_cons (NULL_TREE, tem, args);
+    }
    args = nreverse (args);
    arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
@@ -2244,4 +2255,5 @@
    if (METHOD_STATIC (method))
      {
+      args_size += int_size_in_bytes (TREE_TYPE (klass));
        args = tree_cons (NULL_TREE, klass, args);
        arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
@@ -2249,4 +2261,5 @@

    /* The JNIEnv structure is the first argument to the JNI function.  */
+  args_size += int_size_in_bytes (TREE_TYPE (env_var));
    args = tree_cons (NULL_TREE, env_var, args);
    arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
@@ -2255,26 +2268,31 @@
       function pointer.  _Jv_LookupJNIMethod will throw the appropriate
       exception if this function is not found at runtime.  */
+  tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
    method_sig = build_java_signature (TREE_TYPE (method));
-  lookup_arg =
-    build_tree_list (NULL_TREE,
-		     build_utf8_ref (unmangle_classname
-				     (IDENTIFIER_POINTER (method_sig),
-				      IDENTIFIER_LENGTH (method_sig))));
+  lookup_arg = tree_cons (NULL_TREE,
+                          build_utf8_ref (unmangle_classname
+                                          (IDENTIFIER_POINTER (method_sig),
+                                           IDENTIFIER_LENGTH (method_sig))),
+                          tem);
    tem = DECL_NAME (method);
    lookup_arg
      = tree_cons (NULL_TREE, klass,
-		 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
+                 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
+
+  tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
+
+#ifdef MODIFY_JNI_METHOD_CALL
+  tem = MODIFY_JNI_METHOD_CALL (tem);
+#endif

-  jni_func_type
-    = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
-					       arg_types));
+  jni_func_type = build_pointer_type (tem);

    jnifunc = build (COND_EXPR, ptr_type_node,
-		   meth_var, meth_var,
-		   build (MODIFY_EXPR, ptr_type_node,
-			  meth_var,
-			  build (CALL_EXPR, ptr_type_node,
-				 build_address_of (soft_lookupjnimethod_node),
-				 lookup_arg, NULL_TREE)));
+                   meth_var, meth_var,
+                   build (MODIFY_EXPR, ptr_type_node,
+                          meth_var,
+                          build (CALL_EXPR, ptr_type_node,
+                                 build_address_of (soft_lookupjnimethod_node),
+                                 lookup_arg, NULL_TREE)));

    /* Now we make the actual JNI call via the resulting function
-------------------------------- 8< --------------------------------

Sincerely Yours,
Ranjit.

-- 
Ranjit Mathew        Email: rmathew AT hotmail DOT com
Bangalore,
INDIA.               Web: http://ranjitmathew.tripod.com/





More information about the Java-patches mailing list