This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: FYI: gcjh and PR 1200


I'm checking this in on the trunk.

Today while digging for some other information I ran across an old
patch to fix this PR.  The patch was never cleaned up as I had asked,
so it was never checked in.  I rewrote the patch based on the same
idea, but with a completely new implementation.

This also fixes a lurking bug -- a `jweak' is not the same thing as a
`java.lang.ref.WeakReference'.  JNI weak references are their own
thing.

Tested on x86 against the jni.exp part of the test suite.
(This code only matters for `gcjh -jni'.)

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	Fix for PR java/1200:
	* gjavah.c (throwable_p): New function.
	(decode_signature_piece): Use it.  A `WeakReference' isn't the
	same as a `jweak'.
	Include hashtab.h.
	(gcjh_streq): New function.

Index: gjavah.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/gjavah.c,v
retrieving revision 1.86
diff -u -r1.86 gjavah.c
--- gjavah.c 12 Apr 2002 14:28:49 -0000 1.86
+++ gjavah.c 8 May 2002 01:35:42 -0000
@@ -33,6 +33,7 @@
 #include "javaop.h"
 #include "java-tree.h"
 #include "java-opcodes.h"
+#include "hashtab.h"
 
 #include <getopt.h>
 
@@ -142,6 +143,8 @@
 static void print_field_name PARAMS ((FILE *, JCF *, int, JCF_u2));
 static const unsigned char *super_class_name PARAMS ((JCF *, int *));
 static void print_include PARAMS ((FILE *, const unsigned char *, int));
+static int gcjh_streq PARAMS ((const void *p1, const void *p2));
+static int throwable_p PARAMS ((const unsigned char *signature));
 static const unsigned char *decode_signature_piece
   PARAMS ((FILE *, const unsigned char *, const unsigned char *, int *));
 static void print_class_decls PARAMS ((FILE *, JCF *, int));
@@ -1091,6 +1094,111 @@
     }
 }
 
+/* Like strcmp, but invert the return result for the hash table.  This
+   should probably be in hashtab.c to complement the existing string
+   hash function.  */
+static int
+gcjh_streq (p1, p2)
+     const void *p1, *p2;
+{
+  return ! strcmp ((char *) p1, (char *) p2);
+}
+
+/* Return 1 if the initial (L<classname>;) part of SIGNATURE names a
+   subclass of throwable, or 0 if not.  */
+static int
+throwable_p (signature)
+     const unsigned char *signature;
+{
+  int length;
+  unsigned char *current;
+  int i;
+  int result = 0;
+
+  /* We keep two hash tables of class names.  In one we list all the
+     classes which are subclasses of Throwable.  In the other we will
+     all other classes.  We keep two tables to make the code a bit
+     simpler; we don't have to have a structure mapping class name to
+     a `throwable?' bit.  */
+  static htab_t throw_hash;
+  static htab_t non_throw_hash;
+  static int init_done = 0;
+
+  if (! init_done)
+    {
+      PTR *slot;
+      const unsigned char *str;
+
+      /* Self-initializing.  The cost of this really doesn't matter.
+	 We also don't care about freeing these, either.  */
+      throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
+				(htab_del) free);
+      non_throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
+				    (htab_del) free);
+
+      /* Make sure the root classes show up in the tables.  */
+      str = strdup ("java.lang.Throwable");
+      slot = htab_find_slot (throw_hash, str, INSERT);
+      *slot = (PTR) str;
+
+      str = strdup ("java.lang.Object");
+      slot = htab_find_slot (non_throw_hash, str, INSERT);
+      *slot = (PTR) str;
+
+      init_done = 1;
+    }
+
+  for (length = 0; signature[length] != ';'; ++length)
+    ;
+  current = (unsigned char *) ALLOC (length);
+  for (i = 1; signature[i] != ';'; ++i)
+    current[i - 1] = signature[i] == '/' ? '.' : signature[i];
+  current[i - 1] = '\0';
+
+  /* We don't compute the hash slot here because the table might be
+     modified by the recursion.  In that case the slot could be
+     invalidated.  */
+  if (htab_find (throw_hash, current))
+    result = 1;
+  else if (htab_find (non_throw_hash, current))
+    result = 0;
+  else
+    {
+      JCF jcf;
+      PTR *slot;
+      const char *classfile_name = find_class (current, strlen (current),
+					       &jcf, 0);
+
+      if (! classfile_name)
+	{
+	  fprintf (stderr, "couldn't find class %s\n", current);
+	  found_error = 1;
+	  return 0;
+	}
+      if (jcf_parse_preamble (&jcf) != 0
+	  || jcf_parse_constant_pool (&jcf) != 0
+	  || verify_constant_pool (&jcf) > 0)
+	{
+	  fprintf (stderr, "parse error while reading %s\n", classfile_name);
+	  found_error = 1;
+	  return 0;
+	}
+      jcf_parse_class (&jcf);
+
+      result = throwable_p (super_class_name (&jcf, NULL));
+      slot = htab_find_slot (result ? throw_hash : non_throw_hash,
+			     current, INSERT);
+      *slot = current;
+      current = NULL;
+
+      JCF_FINISH (&jcf);
+    }
+
+  if (current)
+    free (current);
+  return result;
+}
+
 /* Print one piece of a signature.  Returns pointer to next parseable
    character on success, NULL on error.  */
 static const unsigned char *
@@ -1204,24 +1312,15 @@
     case 'L':
       if (flag_jni)
 	{
-	  /* We know about certain types and special-case their
-	     names.
-	     FIXME: something like java.lang.Exception should be
-	     printed as `jthrowable', because it is a subclass.  This
-	     means that gcjh must read the entire hierarchy and
-	     comprehend it.  */
+	  /* We know about certain types and special-case their names.  */
 	  if (! strncmp (signature, "Ljava/lang/String;",
 			 sizeof ("Ljava/lang/String;") -1))
 	    ctype = "jstring";
 	  else if (! strncmp (signature, "Ljava/lang/Class;",
 			      sizeof ("Ljava/lang/Class;") - 1))
 	    ctype = "jclass";
-	  else if (! strncmp (signature, "Ljava/lang/Throwable;",
-			      sizeof ("Ljava/lang/Throwable;") - 1))
+	  else if (throwable_p (signature))
 	    ctype = "jthrowable";
-	  else if (! strncmp (signature, "Ljava/lang/ref/WeakReference;",
-			      sizeof ("Ljava/lang/ref/WeakReference;") - 1))
-	    ctype = "jweak";
 	  else
 	    ctype = "jobject";
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]