]> gcc.gnu.org Git - gcc.git/commitdiff
re PR java/18278 (JNI functions cannot return a weak reference)
authorTom Tromey <tromey@redhat.com>
Tue, 29 Nov 2005 18:34:58 +0000 (18:34 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Tue, 29 Nov 2005 18:34:58 +0000 (18:34 +0000)
gcc/java:
PR java/18278:
* expr.c (build_jni_stub): Unwrap the return value.
* java-tree.h (soft_unwrapjni_node): New define.
(enum java_tree_index): Added JTI_SOFT_UNWRAPJNI_NODE.
* decl.c (java_init_decl_processing): Initialize
soft_unwrapjni_node.
libjava:
PR java/18278:
* testsuite/libjava.jni/pr18278.out: New file.
* testsuite/libjava.jni/pr18278.c: New file.
* testsuite/libjava.jni/pr18278.java: New file.
* include/jvm.h (_Jv_UnwrapJNIweakReference): Declare.
* jni.cc (_Jv_UnwrapJNIweakReference): New function.
(call): Unwrap return value if needed.

From-SVN: r107676

gcc/java/ChangeLog
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
libjava/ChangeLog
libjava/include/jvm.h
libjava/jni.cc
libjava/testsuite/libjava.jni/pr18278.c [new file with mode: 0644]
libjava/testsuite/libjava.jni/pr18278.java [new file with mode: 0644]
libjava/testsuite/libjava.jni/pr18278.out [new file with mode: 0644]

index 60a0aef353dc4916d3ce635d2b49745c61d9d0dd..a8309728abc3f5b40366732ccec359ca0b2338a5 100644 (file)
@@ -1,3 +1,12 @@
+2005-11-28  Tom Tromey  <tromey@redhat.com>
+
+       PR java/18278:
+       * expr.c (build_jni_stub): Unwrap the return value.
+       * java-tree.h (soft_unwrapjni_node): New define.
+       (enum java_tree_index): Added JTI_SOFT_UNWRAPJNI_NODE.
+       * decl.c (java_init_decl_processing): Initialize
+       soft_unwrapjni_node.
+
 2005-11-24  Bryce McKinlay  <mckinlay@redhat.com>
 
         * gcj.texi (gij options): Add -Xss documentation.
index de8f9ada3e985c9acee1019ca4a8c9a55c7a0653..21488ff53546ca023e372262d39e161af5a32ba2 100644 (file)
@@ -1169,6 +1169,12 @@ java_init_decl_processing (void)
                        build_function_type (void_type_node, t),
                        0, NOT_BUILT_IN, NULL, NULL_TREE);
 
+  t = tree_cons (NULL_TREE, object_ptr_type_node, endlink);
+  soft_unwrapjni_node
+    = builtin_function ("_Jv_UnwrapJNIweakReference",
+                       build_function_type (object_ptr_type_node, t),
+                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+
   t = tree_cons (NULL_TREE, int_type_node,
                 tree_cons (NULL_TREE, int_type_node, endlink));
   soft_idiv_node
index a21e1513d6e75539f99fe60b0bff216bd7b0a319..4c2f3f48b896fcf34bb0359e152e35dcb47a2f31 100644 (file)
@@ -2558,8 +2558,17 @@ build_jni_stub (tree method)
   /* If the JNI call returned a result, capture it here.  If we had to
      unwrap JNI object results, we would do that here.  */
   if (res_var != NULL_TREE)
-    call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
-                  res_var, call);
+    {
+      /* If the call returns an object, it may return a JNI weak
+        reference, in which case we must unwrap it.  */
+      if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
+       call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
+                      build_address_of (soft_unwrapjni_node),
+                      build_tree_list (NULL_TREE, call),
+                      NULL_TREE);
+      call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
+                    res_var, call);
+    }
 
   TREE_SIDE_EFFECTS (call) = 1;
   CAN_COMPLETE_NORMALLY (call) = 1;
index 658da38d39a8c95a83988d2135edf13dc1980c99..d3371318960688fa8860adfe6dd658a89cd6d793 100644 (file)
@@ -394,6 +394,7 @@ enum java_tree_index
   JTI_SOFT_LOOKUPJNIMETHOD_NODE,
   JTI_SOFT_GETJNIENVNEWFRAME_NODE,
   JTI_SOFT_JNIPOPSYSTEMFRAME_NODE,
+  JTI_SOFT_UNWRAPJNI_NODE,
   JTI_SOFT_FMOD_NODE,
   JTI_SOFT_IDIV_NODE,
   JTI_SOFT_IREM_NODE,
@@ -663,6 +664,8 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
   java_global_trees[JTI_SOFT_GETJNIENVNEWFRAME_NODE]
 #define soft_jnipopsystemframe_node \
   java_global_trees[JTI_SOFT_JNIPOPSYSTEMFRAME_NODE]
+#define soft_unwrapjni_node \
+  java_global_trees[JTI_SOFT_UNWRAPJNI_NODE]
 #define soft_fmod_node \
   java_global_trees[JTI_SOFT_FMOD_NODE]
 #define soft_idiv_node \
index d303755736f2ead72b241dca7e3a03f79fc03320..2d88d05c1c2bd4053f184a1d5ccd49a29e7e287a 100644 (file)
@@ -1,3 +1,13 @@
+2005-11-28  Tom Tromey  <tromey@redhat.com>
+
+       PR java/18278:
+       * testsuite/libjava.jni/pr18278.out: New file.
+       * testsuite/libjava.jni/pr18278.c: New file.
+       * testsuite/libjava.jni/pr18278.java: New file.
+       * include/jvm.h (_Jv_UnwrapJNIweakReference): Declare.
+       * jni.cc (_Jv_UnwrapJNIweakReference): New function.
+       (call): Unwrap return value if needed.
+
 2005-11-25  Mark Wielaard  <mark@klomp.org>
 
        * standard.omit.in: Remove javax/rmi, org/omg, gnu/CORBA and
index fc104d695f81b2043a03498f75b0010b8f011c06..8d3405947d2f32eb80fbbc7517430d050271ce8a 100644 (file)
@@ -459,6 +459,8 @@ extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
 extern "C" void _Jv_RegisterResource (void *vptr);
 extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);
 
+extern "C" jobject _Jv_UnwrapJNIweakReference (jobject);
+
 extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
                             java::lang::ClassLoader *loader);
 extern jclass _Jv_FindClassFromSignature (char *,
index 13bb12cf5dd5f0520f09ac66e6687fd30bae127a..fd8270657188988c3f86779d900209a429246fe8 100644 (file)
@@ -226,6 +226,12 @@ unwrap (T *obj)
   return reinterpret_cast<T *> (wr->get ());
 }
 
+jobject
+_Jv_UnwrapJNIweakReference (jobject obj)
+{
+  return unwrap (obj);
+}
+
 \f
 
 static jobject JNICALL
@@ -2304,6 +2310,13 @@ _Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
                     ret, real_args);
 #endif
 
+  // We might need to unwrap a JNI weak reference here.
+  if (_this->jni_cif.rtype == &ffi_type_pointer)
+    {
+      _Jv_value *val = (_Jv_value *) ret;
+      val->object_value = unwrap (val->object_value);
+    }
+
   if (sync != NULL)
     _Jv_MonitorExit (sync);
 
diff --git a/libjava/testsuite/libjava.jni/pr18278.c b/libjava/testsuite/libjava.jni/pr18278.c
new file mode 100644 (file)
index 0000000..7ca73a4
--- /dev/null
@@ -0,0 +1,10 @@
+#include <jni.h>
+#include <stdio.h>
+
+#include "pr18278.h"
+
+jobject Java_pr18278_weakRef(JNIEnv *env, jclass cls, jobject data)
+{
+  jobject r =  (* env)->NewWeakGlobalRef(env, data);
+  return r;
+}
diff --git a/libjava/testsuite/libjava.jni/pr18278.java b/libjava/testsuite/libjava.jni/pr18278.java
new file mode 100644 (file)
index 0000000..8a39dde
--- /dev/null
@@ -0,0 +1,13 @@
+public class pr18278 {
+    public pr18278() {}
+
+    public static void main(String[] args) {
+        System.loadLibrary("pr18278");
+       String bob = "Bob";
+       Object o = weakRef("Bob");
+       System.out.println(o);
+       System.out.println(bob == o);
+    }
+
+    static native Object weakRef(Object o);
+}
diff --git a/libjava/testsuite/libjava.jni/pr18278.out b/libjava/testsuite/libjava.jni/pr18278.out
new file mode 100644 (file)
index 0000000..e01142a
--- /dev/null
@@ -0,0 +1,2 @@
+Bob
+true
This page took 0.091454 seconds and 5 git commands to generate.