Commit 6c9c5c1f by Anthony Green Committed by Anthony Green

gjavah.c (print_stub): New function.

        * gjavah.c (print_stub): New function.
        (METHOD_IS_NATIVE): New macro.
        (print_mangled_classname): Make static.
        (HANDLE_END_FIELD): Don't emit fields during stub generation.
        (process_file): Perform stub generation.
        (HANDLE_METHOD): Don't emit class decls during stub
        generation.
        (HANDLE_END_METHOD): Take into account stub generation.
        (print_method_info): Handle stub generation.
        (print_stub): New function.
        (print_cxx_classname): Make signature consistant with others.
        (help): Describe -stubs option.
        (main): Create stub file.
        (version): Use version.c.
        (print_full_cxx_name): New function.
        (print_c_decl): Use print_full_cxx_name.

From-SVN: r28236
parent a08b5082
1999-07-25 Anthony Green <green@cygnus.com>
* gjavah.c (print_stub): New function.
(METHOD_IS_NATIVE): New macro.
(print_mangled_classname): Make static.
(HANDLE_END_FIELD): Don't emit fields during stub generation.
(process_file): Perform stub generation.
(HANDLE_METHOD): Don't emit class decls during stub
generation.
(HANDLE_END_METHOD): Take into account stub generation.
(print_method_info): Handle stub generation.
(print_stub): New function.
(print_cxx_classname): Make signature consistant with others.
(help): Describe -stubs option.
(main): Create stub file.
(version): Use version.c.
(print_full_cxx_name): New function.
(print_c_decl): Use print_full_cxx_name.
Thu Jul 22 12:41:12 1999 Alexandre Petit-Bianco <apbianco@cygnus.com> Thu Jul 22 12:41:12 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* check-init.c (check_init): Handle MAX_EXPR. * check-init.c (check_init): Handle MAX_EXPR.
......
...@@ -33,6 +33,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -33,6 +33,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h" #include "java-tree.h"
#include "java-opcodes.h" #include "java-opcodes.h"
#include "version.c"
/* The output file. */ /* The output file. */
FILE *out = NULL; FILE *out = NULL;
...@@ -88,6 +90,11 @@ static JCF_u2 last_access; ...@@ -88,6 +90,11 @@ static JCF_u2 last_access;
#define METHOD_IS_FINAL(Class, Method) \ #define METHOD_IS_FINAL(Class, Method) \
(((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE))) (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
/* Pass this macro the flags for a method. It will return true if the
method is native. */
#define METHOD_IS_NATIVE(Method) \
((Method) & ACC_NATIVE)
/* We keep a linked list of all method names we have seen. This lets /* We keep a linked list of all method names we have seen. This lets
us determine if a method name and a field name are in conflict. */ us determine if a method name and a field name are in conflict. */
struct method_name struct method_name
...@@ -100,11 +107,15 @@ struct method_name ...@@ -100,11 +107,15 @@ struct method_name
/* List of method names we've seen. */ /* List of method names we've seen. */
static struct method_name *method_name_list; static struct method_name *method_name_list;
static void print_field_info PROTO ((FILE *, JCF*, int, int, JCF_u2)); static void print_field_info PROTO ((FILE*, JCF*, int, int, JCF_u2));
static void print_method_info PROTO ((FILE *, JCF*, int, int, JCF_u2)); static void print_mangled_classname PROTO ((FILE*, JCF*, const char*, int));
static int print_cxx_classname PROTO ((FILE*, const char*, JCF*, int));
static void print_method_info PROTO ((FILE*, JCF*, int, int, JCF_u2));
static void print_c_decl PROTO ((FILE*, JCF*, int, int, int, const char *)); static void print_c_decl PROTO ((FILE*, JCF*, int, int, int, const char *));
static void decompile_method PROTO ((FILE *, JCF *, int)); static void print_stub PROTO ((FILE*, JCF*, int, int, int, const char *));
static void add_class_decl PROTO ((FILE *, JCF *, JCF_u2)); static void print_full_cxx_name PROTO ((FILE*, JCF*, int, int, int, const char *));
static void decompile_method PROTO ((FILE*, JCF*, int));
static void add_class_decl PROTO ((FILE*, JCF*, JCF_u2));
static int java_float_finite PROTO ((jfloat)); static int java_float_finite PROTO ((jfloat));
static int java_double_finite PROTO ((jdouble)); static int java_double_finite PROTO ((jdouble));
...@@ -130,13 +141,13 @@ static int method_pass; ...@@ -130,13 +141,13 @@ static int method_pass;
#define HANDLE_END_FIELD() \ #define HANDLE_END_FIELD() \
if (field_pass) \ if (field_pass) \
{ \ { \
if (out) \ if (out && ! stubs) \
print_field_info (out, jcf, current_field_name, \ print_field_info (out, jcf, current_field_name, \
current_field_signature, \ current_field_signature, \
current_field_flags); \ current_field_flags); \
} \ } \
else \ else \
add_class_decl (out, jcf, current_field_signature); if (! stubs) add_class_decl (out, jcf, current_field_signature);
#define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX) #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
...@@ -151,14 +162,14 @@ static int method_printed = 0; ...@@ -151,14 +162,14 @@ static int method_printed = 0;
print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \ print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
} \ } \
else \ else \
add_class_decl (out, jcf, SIGNATURE); if (! stubs) add_class_decl (out, jcf, SIGNATURE);
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \ #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH); if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
static int decompiled = 0; static int decompiled = 0;
#define HANDLE_END_METHOD() \ #define HANDLE_END_METHOD() \
if (out && method_printed) fputs (decompiled ? "\n" : ";\n", out); if (out && method_printed) fputs (decompiled || stubs ? "\n" : ";\n", out);
#include "jcf-reader.c" #include "jcf-reader.c"
...@@ -562,7 +573,10 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags), ...@@ -562,7 +573,10 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
return; return;
} }
if (! stubs)
{
method_printed = 1; method_printed = 1;
generate_access (stream, flags); generate_access (stream, flags);
fputs (" ", out); fputs (" ", out);
...@@ -580,6 +594,15 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags), ...@@ -580,6 +594,15 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
fputs (" = 0", out); fputs (" = 0", out);
else else
method_declared = 1; method_declared = 1;
}
else
{
if (METHOD_IS_NATIVE(flags))
{
method_printed = 1;
print_stub (out, jcf, name_index, sig_index, is_init, override);
}
}
} }
/* Try to decompile a method body. Right now we just try to handle a /* Try to decompile a method body. Right now we just try to handle a
...@@ -791,6 +814,26 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init, ...@@ -791,6 +814,26 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
/* Now print the name of the thing. */ /* Now print the name of the thing. */
if (need_space) if (need_space)
fputs (" ", stream); fputs (" ", stream);
print_full_cxx_name (stream, jcf, name_index,
signature_index, is_init, name_override);
}
}
// Print the unqualified method name followed by the signature.
static void
DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index, is_init, name_override),
FILE* stream AND JCF* jcf
AND int name_index AND int signature_index AND int is_init
AND const char *name_override)
{
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
register unsigned char *str = str0;
unsigned char *limit = str + length;
int need_space = 0;
int is_method = str[0] == '(';
unsigned char *next;
if (name_override) if (name_override)
fputs (name_override, stream); fputs (name_override, stream);
else if (name_index) else if (name_index)
...@@ -825,6 +868,67 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init, ...@@ -825,6 +868,67 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
fputs (")", stream); fputs (")", stream);
} }
}
static void
DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
name_override),
FILE* stream AND JCF* jcf
AND int name_index AND int signature_index
AND int is_init AND const char *name_override)
{
if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
{
fprintf (stream, "<not a UTF8 constant>");
found_error = 1;
}
else
{
int length = JPOOL_UTF_LENGTH (jcf, signature_index);
unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
register unsigned char *str = str0;
unsigned char *limit = str + length;
int need_space = 0;
int is_method = str[0] == '(';
unsigned char *next;
/* If printing a method, skip to the return signature and print
that first. However, there is no return value if this is a
constructor. */
if (is_method && ! is_init)
{
while (str < limit)
{
int ch = *str++;
if (ch == ')')
break;
}
}
/* If printing a field or an ordinary method, then print the
"return value" now. */
if (! is_method || ! is_init)
{
next = decode_signature_piece (stream, str, limit, &need_space);
if (! next)
{
fprintf (stderr, "unparseable signature: `%s'\n", str0);
found_error = 1;
return;
}
}
/* Now print the name of the thing. */
print_cxx_classname (stream, "\n", jcf, jcf->this_class);
fputs ("::", stream);
print_full_cxx_name (stream, jcf, name_index,
signature_index, is_init, name_override);
fputs ("\n{\n JvFail (\"", stream);
print_cxx_classname (stream, "", jcf, jcf->this_class);
fputs ("::", stream);
print_full_cxx_name (stream, jcf, name_index,
signature_index, is_init, name_override);
fputs (" not implemented\");\n}\n\n", stream);
} }
} }
...@@ -846,7 +950,7 @@ DEFUN(print_mangled_classname, (stream, jcf, prefix, index), ...@@ -846,7 +950,7 @@ DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
static int static int
print_cxx_classname (stream, prefix, jcf, index) print_cxx_classname (stream, prefix, jcf, index)
FILE *stream; FILE *stream;
char *prefix; const char *prefix;
JCF *jcf; JCF *jcf;
int index; int index;
{ {
...@@ -1204,11 +1308,23 @@ DEFUN(process_file, (jcf, out), ...@@ -1204,11 +1308,23 @@ DEFUN(process_file, (jcf, out),
jcf_parse_class (jcf); jcf_parse_class (jcf);
if (written_class_count++ == 0 && out) if (written_class_count++ == 0 && out)
if (! stubs)
fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n", fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
out); out);
else
{
fputs ("// This file was created by `gcjh -stubs'. It is -*- c++ -*-.
//
// This file is intended to give you a head start on implementing native
// methods using CNI.
// Be aware: running `gcjh -stubs' once more for this class may overwrite any
// edits you have made to this file.\n\n", out);
}
if (out) if (out)
{ {
if (! stubs)
{
print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class); print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
fprintf (out, "__\n"); fprintf (out, "__\n");
...@@ -1219,9 +1335,8 @@ DEFUN(process_file, (jcf, out), ...@@ -1219,9 +1335,8 @@ DEFUN(process_file, (jcf, out),
by g++. This works as long as method and fields are not by g++. This works as long as method and fields are not
added by the user. */ added by the user. */
fprintf (out, "#pragma interface\n"); fprintf (out, "#pragma interface\n");
}
if (jcf->super_class && out) if (jcf->super_class)
{ {
int super_length; int super_length;
unsigned char *supername = super_class_name (jcf, &super_length); unsigned char *supername = super_class_name (jcf, &super_length);
...@@ -1229,6 +1344,14 @@ DEFUN(process_file, (jcf, out), ...@@ -1229,6 +1344,14 @@ DEFUN(process_file, (jcf, out),
fputs ("\n", out); fputs ("\n", out);
print_include (out, supername, super_length); print_include (out, supername, super_length);
} }
}
else
{
/* Strip off the ".class" portion of the name when printing
the include file name. */
print_include (out, jcf->classname, strlen (jcf->classname) - 6);
}
}
/* We want to parse the methods first. But we need to find where /* We want to parse the methods first. But we need to find where
they start. So first we skip the fields, then parse the methods. they start. So first we skip the fields, then parse the methods.
...@@ -1246,31 +1369,37 @@ DEFUN(process_file, (jcf, out), ...@@ -1246,31 +1369,37 @@ DEFUN(process_file, (jcf, out),
if (out) if (out)
{ {
fputs ("\n", out); fputs ("\n", out);
if (! stubs)
print_class_decls (out, jcf, jcf->this_class); print_class_decls (out, jcf, jcf->this_class);
for (i = 0; i < prepend_count; ++i) for (i = 0; i < prepend_count; ++i)
fprintf (out, "%s\n", prepend_specs[i]); fprintf (out, "%s\n", prepend_specs[i]);
if (prepend_count > 0) if (prepend_count > 0)
fputc ('\n', out); fputc ('\n', out);
}
if (out && ! print_cxx_classname (out, "class ", jcf, jcf->this_class)) if (! stubs)
{
if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
{ {
fprintf (stderr, "class is of array type\n"); fprintf (stderr, "class is of array type\n");
found_error = 1; found_error = 1;
return; return;
} }
if (out && jcf->super_class) if (jcf->super_class)
{ {
if (! print_cxx_classname (out, " : public ", jcf, jcf->super_class)) if (! print_cxx_classname (out, " : public ",
jcf, jcf->super_class))
{ {
fprintf (stderr, "base class is of array type\n"); fprintf (stderr, "base class is of array type\n");
found_error = 1; found_error = 1;
return; return;
} }
} }
if (out)
fputs ("\n{\n", out); fputs ("\n{\n", out);
}
}
/* Now go back for second pass over methods and fields. */ /* Now go back for second pass over methods and fields. */
JCF_SEEK (jcf, method_start); JCF_SEEK (jcf, method_start);
...@@ -1297,6 +1426,7 @@ DEFUN(process_file, (jcf, out), ...@@ -1297,6 +1426,7 @@ DEFUN(process_file, (jcf, out),
for (i = 0; i < add_count; ++i) for (i = 0; i < add_count; ++i)
fprintf (out, " %s\n", add_specs[i]); fprintf (out, " %s\n", add_specs[i]);
if (! stubs)
fputs ("};\n", out); fputs ("};\n", out);
if (append_count > 0) if (append_count > 0)
...@@ -1304,9 +1434,13 @@ DEFUN(process_file, (jcf, out), ...@@ -1304,9 +1434,13 @@ DEFUN(process_file, (jcf, out),
for (i = 0; i < append_count; ++i) for (i = 0; i < append_count; ++i)
fprintf (out, "%s\n", append_specs[i]); fprintf (out, "%s\n", append_specs[i]);
print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class); if (!stubs)
{
print_mangled_classname (out, jcf,
"\n#endif /* __", jcf->this_class);
fprintf (out, "__ */\n"); fprintf (out, "__ */\n");
} }
}
} }
static void static void
...@@ -1327,6 +1461,7 @@ help () ...@@ -1327,6 +1461,7 @@ help ()
printf (" -d DIRECTORY Set output directory name\n"); printf (" -d DIRECTORY Set output directory name\n");
printf (" --help Print this help, then exit\n"); printf (" --help Print this help, then exit\n");
printf (" -o FILE Set output file name\n"); printf (" -o FILE Set output file name\n");
printf (" -stubs Generate a C++ implementation stub file\n");
printf (" -td DIRECTORY Set temporary directory name\n"); printf (" -td DIRECTORY Set temporary directory name\n");
printf (" -v, --verbose Print extra information while running\n"); printf (" -v, --verbose Print extra information while running\n");
printf (" --version Print version number, then exit\n"); printf (" --version Print version number, then exit\n");
...@@ -1346,8 +1481,8 @@ static void ...@@ -1346,8 +1481,8 @@ static void
version () version ()
{ {
/* FIXME: use version.c? */ /* FIXME: use version.c? */
printf ("gcjh (GNU gcc) 0.0\n\n"); printf ("gcjh (%s)\n\n", version_string);
printf ("Copyright (C) 1998 Free Software Foundation, Inc.\n"); printf ("Copyright (C) 1998, 1999 Free Software Foundation, Inc.\n");
printf ("This is free software; see the source for copying conditions. There is NO\n"); printf ("This is free software; see the source for copying conditions. There is NO\n");
printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
exit (0); exit (0);
...@@ -1548,7 +1683,7 @@ DEFUN(main, (argc, argv), ...@@ -1548,7 +1683,7 @@ DEFUN(main, (argc, argv),
{ {
int dir_len = strlen (output_directory); int dir_len = strlen (output_directory);
int i, classname_length = strlen (classname); int i, classname_length = strlen (classname);
current_output_file = (char*) ALLOC (dir_len + classname_length + 4); current_output_file = (char*) ALLOC (dir_len + classname_length + 5);
strcpy (current_output_file, output_directory); strcpy (current_output_file, output_directory);
if (dir_len > 0 && output_directory[dir_len-1] != '/') if (dir_len > 0 && output_directory[dir_len-1] != '/')
current_output_file[dir_len++] = '/'; current_output_file[dir_len++] = '/';
...@@ -1574,7 +1709,8 @@ DEFUN(main, (argc, argv), ...@@ -1574,7 +1709,8 @@ DEFUN(main, (argc, argv),
jcf_dependency_set_dep_file (current_output_file); jcf_dependency_set_dep_file (current_output_file);
} }
} }
strcpy (current_output_file + dir_len, ".h"); strcpy (current_output_file + dir_len,
stubs ? ".cc" : ".h");
jcf_dependency_set_target (current_output_file); jcf_dependency_set_target (current_output_file);
if (! suppress_output) if (! suppress_output)
{ {
...@@ -1601,10 +1737,9 @@ DEFUN(main, (argc, argv), ...@@ -1601,10 +1737,9 @@ DEFUN(main, (argc, argv),
/* TODO: /* TODO:
* Do whatever the javah -stubs flag does.
* Emit "structure forward declarations" when needed. * Emit "structure forward declarations" when needed.
* Generate C headers, like javah * Generate C headers, like javah
*/ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment