This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Java: Fix gcjh JNI bug
- From: Bryce McKinlay <bryce at waitaki dot otago dot ac dot nz>
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Cc: tromey at redhat dot com
- Date: Thu, 30 May 2002 18:56:02 +1200
- Subject: Java: Fix gcjh JNI bug
"gcjh -jni" now looks at superclasses in order to determine if a given
class is a throwable. Unfortunatly if it tried to do this for any class
which did not directly extend throwable it would give an error like:
"couldn't find class `ava.lang.Object'."
Because it was calling itself with a classname extracted from the super
field of a classfile while it expected the class name as a signature
fragment (ie with a leading 'L'), and so was stripping the first
character. In addition the super class name obtained directly from the
classfile data is not null terminated, so we must copy it into a
null-terminated string before recursing.
This patch fixes, ok to commit?
regards
Bryce.
2002-05-30 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* gjavah.c (throwable_p): Accept argument as either a classname or
signature fragment. Create null-terminated classname string for super
when calling itself recursively.
(decode_signature_piece): Skip first character from class name
signature when calling throwable_p.
Index: gjavah.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/gjavah.c,v
retrieving revision 1.89
diff -u -r1.89 gjavah.c
--- gjavah.c 19 May 2002 16:25:51 -0000 1.89
+++ gjavah.c 30 May 2002 06:41:35 -0000
@@ -1104,11 +1104,12 @@
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. */
+/* Return 1 if the initial part of CLNAME names a subclass of throwable,
+ or 0 if not. CLNAME may be extracted from a signature, and can be
+ terminated with either `;' or NULL. */
static int
-throwable_p (signature)
- const unsigned char *signature;
+throwable_p (clname)
+ const unsigned char *clname;
{
int length;
unsigned char *current;
@@ -1148,12 +1149,12 @@
init_done = 1;
}
- for (length = 0; signature[length] != ';'; ++length)
+ for (length = 0; clname[length] != ';' && clname[length] != '\0'; ++length)
;
current = (unsigned char *) ALLOC (length);
- for (i = 1; signature[i] != ';'; ++i)
- current[i - 1] = signature[i] == '/' ? '.' : signature[i];
- current[i - 1] = '\0';
+ for (i = 0; i < length; ++i)
+ current[i] = clname[i] == '/' ? '.' : clname[i];
+ current[length] = '\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
@@ -1166,6 +1167,8 @@
{
JCF jcf;
PTR *slot;
+ unsigned char *super, *tmp;
+ int super_length = -1;
const char *classfile_name = find_class (current, strlen (current),
&jcf, 0);
@@ -1185,7 +1188,12 @@
}
jcf_parse_class (&jcf);
- result = throwable_p (super_class_name (&jcf, NULL));
+ tmp = (unsigned char *) super_class_name (&jcf, &super_length);
+ super = (unsigned char *) ALLOC (super_length + 1);
+ memcpy (super, tmp, super_length);
+ super[super_length] = '\0';
+
+ result = throwable_p (super);
slot = htab_find_slot (result ? throw_hash : non_throw_hash,
current, INSERT);
*slot = current;
@@ -1317,7 +1325,8 @@
else if (! strncmp (signature, "Ljava/lang/Class;",
sizeof ("Ljava/lang/Class;") - 1))
ctype = "jclass";
- else if (throwable_p (signature))
+ /* Skip leading 'L' for throwable_p call. */
+ else if (throwable_p (signature + 1))
ctype = "jthrowable";
else
ctype = "jobject";