Patch: FYI: Fix PR 18278
Tom Tromey
tromey@redhat.com
Tue Nov 29 18:21:00 GMT 2005
I'm checking this in on the trunk and the 4.1 branch.
This fixes PR 18278. Now we unwrap the return value of a JNI method
if the method returns an object. This lets us correctly handle user
functions which return JNI weak references. We hit this while running
a java-gnome application.
Test case included.
Tom
Index: gcc/java/ChangeLog
from 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.
Index: libjava/ChangeLog
from 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.
Index: gcc/java/decl.c
===================================================================
--- gcc/java/decl.c (revision 107670)
+++ gcc/java/decl.c (working copy)
@@ -1169,6 +1169,12 @@
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: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c (revision 107670)
+++ gcc/java/expr.c (working copy)
@@ -2558,8 +2558,17 @@
/* 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: gcc/java/java-tree.h
===================================================================
--- gcc/java/java-tree.h (revision 107670)
+++ gcc/java/java-tree.h (working copy)
@@ -394,6 +394,7 @@
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 @@
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: libjava/include/jvm.h
===================================================================
--- libjava/include/jvm.h (revision 107670)
+++ libjava/include/jvm.h (working copy)
@@ -459,6 +459,8 @@
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: libjava/testsuite/libjava.jni/pr18278.java
===================================================================
--- libjava/testsuite/libjava.jni/pr18278.java (revision 0)
+++ libjava/testsuite/libjava.jni/pr18278.java (revision 0)
@@ -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);
+}
Index: libjava/testsuite/libjava.jni/pr18278.out
===================================================================
--- libjava/testsuite/libjava.jni/pr18278.out (revision 0)
+++ libjava/testsuite/libjava.jni/pr18278.out (revision 0)
@@ -0,0 +1,2 @@
+Bob
+true
Index: libjava/testsuite/libjava.jni/pr18278.c
===================================================================
--- libjava/testsuite/libjava.jni/pr18278.c (revision 0)
+++ libjava/testsuite/libjava.jni/pr18278.c (revision 0)
@@ -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;
+}
Index: libjava/jni.cc
===================================================================
--- libjava/jni.cc (revision 107670)
+++ libjava/jni.cc (working copy)
@@ -226,6 +226,12 @@
return reinterpret_cast<T *> (wr->get ());
}
+jobject
+_Jv_UnwrapJNIweakReference (jobject obj)
+{
+ return unwrap (obj);
+}
+
static jobject JNICALL
@@ -2304,6 +2310,13 @@
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);
More information about the Java-patches
mailing list