re PR java/1200 (gcjh -jni doesn't respect class hierarchy)
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. From-SVN: r53275
This commit is contained in:
parent
db84f1bded
commit
6b9b5de22a
@ -1,3 +1,12 @@
|
||||
2002-05-07 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.
|
||||
|
||||
2002-05-07 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* parse.y (finish_for_loop): Fix if statement.
|
||||
|
@ -33,6 +33,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
||||
#include "javaop.h"
|
||||
#include "java-tree.h"
|
||||
#include "java-opcodes.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
@ -142,6 +143,8 @@ static char *get_field_name PARAMS ((JCF *, int, JCF_u2));
|
||||
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 @@ decompile_method (out, jcf, code_len)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ decode_signature_piece (stream, signature, limit, need_space)
|
||||
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";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user