summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-22 20:51:55 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-22 20:51:55 +0000
commitcaa8fa373e7ffb8f83d65cede231ca2a28818d2d (patch)
treeb7d7c4804e0025ba42eee223253a8402fbee444d /gcc/java
parent3d72c7bc7e4ec0637c077f2d060514906448a7fa (diff)
downloadgcc-caa8fa373e7ffb8f83d65cede231ca2a28818d2d.tar.gz
* gcj.texi (Input and output files): Mention non-class entries.
* decl.c (java_init_decl_processing): Call init_resource_processing. * java-tree.h (compile_resource_data, write_resource_constructor, compile_resource_file, init_resource_processing): Declare. * config-lang.in (gtfiles): Added resource.c. * Make-lang.in (gt-java-resource.h): New target. (JAVA_OBJS): Added resource.o. (java/resource.o): New target. * resource.c: New file. * class.c (compile_resource_file): Moved to resource.c. (registerResource_libfunc): Likewise. (utf8_decl_list): Mark with GTY; now static. * jcf-parse.c (classify_zip_file): New function. (parse_zip_file_entries): Use it; compile .properties files. (process_zip_dir): Use classify_zip_file and compute_class_name. Don't write class name into zip directory. (java_parse_file): Call write_resource_constructor. (compute_class_name): New function. * jcf-io.c (read_zip_member): Reindented. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61614 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog23
-rw-r--r--gcc/java/Make-lang.in7
-rw-r--r--gcc/java/class.c109
-rw-r--r--gcc/java/config-lang.in2
-rw-r--r--gcc/java/decl.c1
-rw-r--r--gcc/java/except.c33
-rw-r--r--gcc/java/gcj.texi5
-rw-r--r--gcc/java/java-tree.h7
-rw-r--r--gcc/java/jcf-io.c80
-rw-r--r--gcc/java/jcf-parse.c171
-rw-r--r--gcc/java/resource.c199
11 files changed, 434 insertions, 203 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 346dd6bea47..bdb9917d6cb 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,26 @@
+2003-01-22 Tom Tromey <tromey@redhat.com>
+
+ * gcj.texi (Input and output files): Mention non-class entries.
+ * decl.c (java_init_decl_processing): Call
+ init_resource_processing.
+ * java-tree.h (compile_resource_data, write_resource_constructor,
+ compile_resource_file, init_resource_processing): Declare.
+ * config-lang.in (gtfiles): Added resource.c.
+ * Make-lang.in (gt-java-resource.h): New target.
+ (JAVA_OBJS): Added resource.o.
+ (java/resource.o): New target.
+ * resource.c: New file.
+ * class.c (compile_resource_file): Moved to resource.c.
+ (registerResource_libfunc): Likewise.
+ (utf8_decl_list): Mark with GTY; now static.
+ * jcf-parse.c (classify_zip_file): New function.
+ (parse_zip_file_entries): Use it; compile .properties files.
+ (process_zip_dir): Use classify_zip_file and compute_class_name.
+ Don't write class name into zip directory.
+ (java_parse_file): Call write_resource_constructor.
+ (compute_class_name): New function.
+ * jcf-io.c (read_zip_member): Reindented.
+
2003-01-21 Tom Tromey <tromey@redhat.com>
* class.c (supers_all_compiled): New function.
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 59c8d0eb18b..fc930232051 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -102,13 +102,13 @@ $(srcdir)/java/keyword.h: $(srcdir)/java/keyword.gperf
gt-java-class.h gt-java-constants.h gt-java-decl.h : s-gtype ; @true
gt-java-expr.h gt-java-jcf-parse.h gt-java-jcf-write.h : s-gtype ; @true
gt-java-lang.h gt-java-mangle.h gt-java-parse.h : s-gtype ; @true
-gt-java-builtins.h gtype-java.h : s-gtype ; @true
+gt-java-builtins.h gtype-java.h gt-java-resource.h : s-gtype ; @true
# Executables built by this Makefile:
JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
java/constants.o java/lang.o java/typeck.o java/except.o java/verify.o \
java/zextract.o java/jcf-io.o java/jcf-parse.o java/mangle.o \
- java/mangle_name.o java/builtins.o \
+ java/mangle_name.o java/builtins.o java/resource.o \
java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o mkdeps.o
@@ -324,6 +324,9 @@ java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
$(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(GGC_H)
java/parse-scan.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
$(JAVA_LEX_C) java/parse.h java/lex.h
+java/resource.o: java/resource.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(JAVA_TREE_H) $(RTL_H) java/jcf.h java/parse.h toplev.h output.h $(GGC_H) \
+ $(TARGET_H) function.h gt-java-resource.h
java/typeck.o: java/typeck.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
java/convert.h toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) real.h
java/verify.o: java/verify.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 1e0e83a7520..d0953cce4ed 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -61,7 +61,6 @@ static int assume_compiled (const char *);
static tree build_method_symbols_entry (tree);
static GTY(()) rtx registerClass_libfunc;
-static GTY(()) rtx registerResource_libfunc;
struct obstack temporary_obstack;
@@ -742,111 +741,7 @@ hashUtf8String (const char *str, int len)
return hash;
}
-/* Generate a byte array representing the contents of FILENAME. The
- array is assigned a unique local symbol. The array represents a
- compiled Java resource, which is accessed by the runtime using
- NAME. */
-void
-compile_resource_file (char *name, const char *filename)
-{
- struct stat stat_buf;
- int fd;
- char *buffer;
- char buf[60];
- tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
- static int Jr_count = 0;
-
- fd = open (filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- {
- perror ("Failed to read resource file");
- return;
- }
- if (fstat (fd, &stat_buf) != 0
- || ! S_ISREG (stat_buf.st_mode))
- {
- perror ("Could not figure length of resource file");
- return;
- }
- buffer = xmalloc (strlen (name) + stat_buf.st_size);
- strcpy (buffer, name);
- read (fd, buffer + strlen (name), stat_buf.st_size);
- close (fd);
- data_type = build_prim_array_type (unsigned_byte_type_node,
- strlen (name) + stat_buf.st_size);
- rtype = make_node (RECORD_TYPE);
- PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "data", data_type);
- FINISH_RECORD (rtype);
- START_RECORD_CONSTRUCTOR (rinit, rtype);
- PUSH_FIELD_VALUE (rinit, "name_length",
- build_int_2 (strlen (name), 0));
- PUSH_FIELD_VALUE (rinit, "resource_length",
- build_int_2 (stat_buf.st_size, 0));
- data = build_string (strlen(name) + stat_buf.st_size, buffer);
- TREE_TYPE (data) = data_type;
- PUSH_FIELD_VALUE (rinit, "data", data);
- FINISH_RECORD_CONSTRUCTOR (rinit);
- TREE_CONSTANT (rinit) = 1;
-
- /* Generate a unique-enough identifier. */
- sprintf(buf, "_Jr%d", ++Jr_count);
-
- decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
- TREE_STATIC (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- TREE_READONLY (decl) = 1;
- TREE_THIS_VOLATILE (decl) = 0;
- DECL_INITIAL (decl) = rinit;
- layout_decl (decl, 0);
- pushdecl (decl);
- rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
- make_decl_rtl (decl, (char*) 0);
- assemble_variable (decl, 1, 0, 0);
-
- {
- tree init_name = get_file_function_name ('I');
- tree init_type = build_function_type (void_type_node, end_params_node);
- tree init_decl;
-
- init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
- SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
- TREE_STATIC (init_decl) = 1;
- current_function_decl = init_decl;
- DECL_RESULT (init_decl) = build_decl (RESULT_DECL,
- NULL_TREE, void_type_node);
-
- /* It can be a static function as long as collect2 does not have
- to scan the object file to find its ctor/dtor routine. */
- TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
-
- pushlevel (0);
- make_decl_rtl (init_decl, NULL);
- init_function_start (init_decl, input_filename, 0);
- expand_function_start (init_decl, 0);
-
- emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
- gen_rtx (SYMBOL_REF, Pmode, buf),
- Pmode);
-
- expand_function_end (input_filename, 0, 0);
- poplevel (1, 0, 1);
- {
- /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
- int saved_flag = flag_inline_functions;
- flag_inline_functions = 0;
- rest_of_compilation (init_decl);
- flag_inline_functions = saved_flag;
- }
- current_function_decl = NULL_TREE;
- (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
- DEFAULT_INIT_PRIORITY);
- }
-}
-
-tree utf8_decl_list = NULL_TREE;
+static GTY(()) tree utf8_decl_list = NULL_TREE;
tree
build_utf8_ref (tree name)
@@ -2209,8 +2104,6 @@ void
init_class_processing (void)
{
registerClass_libfunc = gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterClass");
- registerResource_libfunc =
- gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterResource");
fields_ident = get_identifier ("fields");
info_ident = get_identifier ("info");
gcc_obstack_init (&temporary_obstack);
diff --git a/gcc/java/config-lang.in b/gcc/java/config-lang.in
index 05a6fdff7e7..41c5f915a71 100644
--- a/gcc/java/config-lang.in
+++ b/gcc/java/config-lang.in
@@ -36,7 +36,7 @@ compilers="jc1\$(exeext) jvgenmain\$(exeext)"
stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
-gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/jcf.h \$(srcdir)/java/lex.h \$(srcdir)/java/parse.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y"
+gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/jcf.h \$(srcdir)/java/lex.h \$(srcdir)/java/parse.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y \$(srcdir)/java/resource.c"
target_libs=${libgcj_saved}
lang_dirs="zlib fastjar"
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 99c2652160e..218d4baae92 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -397,6 +397,7 @@ java_init_decl_processing (void)
tree t;
init_class_processing ();
+ init_resource_processing ();
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
diff --git a/gcc/java/except.c b/gcc/java/except.c
index 9ad41a658ba..dcfefb7df23 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -324,10 +324,35 @@ prepare_eh_table_type (tree type)
else if (is_compiled_class (type))
exp = build_class_ref (type);
else
- exp = fold (build
- (PLUS_EXPR, ptr_type_node,
- build_utf8_ref (DECL_NAME (TYPE_NAME (type))),
- size_one_node));
+ {
+ tree ctype = make_node (RECORD_TYPE);
+ tree field = NULL_TREE;
+ tree cinit, decl;
+ tree utf8_ref = build_utf8_ref (DECL_NAME (TYPE_NAME (type)));
+ char buf[64];
+ sprintf (buf, "%s_ref",
+ IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (utf8_ref, 0))));
+ PUSH_FIELD (ctype, field, "dummy", ptr_type_node);
+ PUSH_FIELD (ctype, field, "utf8", utf8const_ptr_type);
+ FINISH_RECORD (ctype);
+ START_RECORD_CONSTRUCTOR (cinit, ctype);
+ PUSH_FIELD_VALUE (cinit, "dummy", integer_minus_one_node);
+ PUSH_FIELD_VALUE (cinit, "utf8", utf8_ref);
+ FINISH_RECORD_CONSTRUCTOR (cinit);
+ TREE_CONSTANT (cinit) = 1;
+ decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
+ TREE_STATIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ TREE_THIS_VOLATILE (decl) = 0;
+ DECL_INITIAL (decl) = cinit;
+ layout_decl (decl, 0);
+ pushdecl (decl);
+ rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
+ make_decl_rtl (decl, (char*) 0);
+ exp = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
+ }
return exp;
}
diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi
index 8a40b7739f0..f9518d7bd64 100644
--- a/gcc/java/gcj.texi
+++ b/gcc/java/gcj.texi
@@ -182,7 +182,10 @@ Java bytecode files.
@item @var{file}.zip
@itemx @var{file}.jar
An archive containing one or more @code{.class} files, all of
-which are compiled. The archive may be compressed.
+which are compiled. The archive may be compressed. Files in
+an archive which don't end with @samp{.class} are treated as
+resource files; they are copmiled into the resulting object file
+as @samp{core:} URLs.
@item @@@var{file}
A file containing a whitespace-separated list of input file names.
(Currently, these must all be @code{.java} source files, but that
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 88e6f07622b..ccedb9a2e6d 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1299,6 +1299,13 @@ struct rtx_def * java_expand_expr (tree, rtx, enum machine_mode, int);
extern void java_inlining_merge_static_initializers (tree, void *);
extern void java_inlining_map_static_initializers (tree, void *);
+extern void compile_resource_data PARAMS ((char *name, const char *buffer,
+ int length));
+extern void write_resource_constructor PARAMS ((void));
+extern void compile_resource_file PARAMS ((char *name, const char *filename));
+extern void init_resource_processing PARAMS ((void));
+
+
#define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
/* Access flags etc for a method (a FUNCTION_DECL): */
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index abc20736b7d..5d6ef25d8ba 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -186,48 +186,48 @@ open_in_zip (JCF *jcf, const char *zipfile, const char *zipmember,
int
read_zip_member (JCF *jcf, ZipDirectory *zipd, ZipFile *zipf)
{
- jcf->filbuf = jcf_unexpected_eof;
- jcf->zipd = (void *)zipd;
+ jcf->filbuf = jcf_unexpected_eof;
+ jcf->zipd = (void *)zipd;
- if (zipd->compression_method == Z_NO_COMPRESSION)
- {
- jcf->buffer = ALLOC (zipd->size);
- jcf->buffer_end = jcf->buffer + zipd->size;
- jcf->read_ptr = jcf->buffer;
- jcf->read_end = jcf->buffer_end;
- if (lseek (zipf->fd, zipd->filestart, 0) < 0
- || read (zipf->fd, jcf->buffer, zipd->size) != (long) zipd->size)
- return -2;
- }
- else
- {
- char *buffer;
- z_stream d_stream; /* decompression stream */
- d_stream.zalloc = (alloc_func) 0;
- d_stream.zfree = (free_func) 0;
- d_stream.opaque = (voidpf) 0;
-
- jcf->buffer = ALLOC (zipd->uncompressed_size);
- d_stream.next_out = jcf->buffer;
- d_stream.avail_out = zipd->uncompressed_size;
- jcf->buffer_end = jcf->buffer + zipd->uncompressed_size;
- jcf->read_ptr = jcf->buffer;
- jcf->read_end = jcf->buffer_end;
- buffer = ALLOC (zipd->size);
- d_stream.next_in = buffer;
- d_stream.avail_in = zipd->size;
- if (lseek (zipf->fd, zipd->filestart, 0) < 0
- || read (zipf->fd, buffer, zipd->size) != (long) zipd->size)
- return -2;
- /* Handle NO_HEADER using undocumented zlib feature.
- This is a very common hack. */
- inflateInit2 (&d_stream, -MAX_WBITS);
- inflate (&d_stream, Z_NO_FLUSH);
- inflateEnd (&d_stream);
- FREE (buffer);
- }
+ if (zipd->compression_method == Z_NO_COMPRESSION)
+ {
+ jcf->buffer = ALLOC (zipd->size);
+ jcf->buffer_end = jcf->buffer + zipd->size;
+ jcf->read_ptr = jcf->buffer;
+ jcf->read_end = jcf->buffer_end;
+ if (lseek (zipf->fd, zipd->filestart, 0) < 0
+ || read (zipf->fd, jcf->buffer, zipd->size) != (long) zipd->size)
+ return -2;
+ }
+ else
+ {
+ char *buffer;
+ z_stream d_stream; /* decompression stream */
+ d_stream.zalloc = (alloc_func) 0;
+ d_stream.zfree = (free_func) 0;
+ d_stream.opaque = (voidpf) 0;
+
+ jcf->buffer = ALLOC (zipd->uncompressed_size);
+ d_stream.next_out = jcf->buffer;
+ d_stream.avail_out = zipd->uncompressed_size;
+ jcf->buffer_end = jcf->buffer + zipd->uncompressed_size;
+ jcf->read_ptr = jcf->buffer;
+ jcf->read_end = jcf->buffer_end;
+ buffer = ALLOC (zipd->size);
+ d_stream.next_in = buffer;
+ d_stream.avail_in = zipd->size;
+ if (lseek (zipf->fd, zipd->filestart, 0) < 0
+ || read (zipf->fd, buffer, zipd->size) != (long) zipd->size)
+ return -2;
+ /* Handle NO_HEADER using undocumented zlib feature.
+ This is a very common hack. */
+ inflateInit2 (&d_stream, -MAX_WBITS);
+ inflate (&d_stream, Z_NO_FLUSH);
+ inflateEnd (&d_stream);
+ FREE (buffer);
+ }
- return 0;
+ return 0;
}
const char *
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index 892e5616b5f..a29da453a8b 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -94,6 +94,8 @@ static struct ZipFile *localToFile;
/* Declarations of some functions used here. */
static void handle_innerclass_attribute (int count, JCF *);
static tree give_name_to_class (JCF *jcf, int index);
+static char *compute_class_name (struct ZipDirectory *zdir);
+static int classify_zip_file (struct ZipDirectory *zdir);
static void parse_zip_file_entries (void);
static void process_zip_dir (FILE *);
static void parse_source_file_1 (tree, FILE *);
@@ -1012,7 +1014,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
finput = fopen (IDENTIFIER_POINTER (name), "rb");
if (finput == NULL)
fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name));
-
+
#ifdef IO_BUFFER_SIZE
setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
_IOFBF, IO_BUFFER_SIZE);
@@ -1047,7 +1049,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
if (open_in_zip (main_jcf, input_filename, NULL, 0) < 0)
fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name));
localToFile = SeenZipFiles;
- /* Register all the class defined there. */
+ /* Register all the classes defined there. */
process_zip_dir (main_jcf->read_state);
parse_zip_file_entries ();
/*
@@ -1100,6 +1102,51 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
if (flag_indirect_dispatch)
emit_offset_symbol_table ();
}
+
+ write_resource_constructor ();
+}
+
+/* Return the name of the class corresponding to the name of the file
+ in this zip entry. The result is newly allocated using ALLOC. */
+static char *
+compute_class_name (struct ZipDirectory *zdir)
+{
+ char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
+ char *class_name;
+ int j;
+
+ class_name = ALLOC (zdir->filename_length + 1 - 6);
+ strncpy (class_name, class_name_in_zip_dir, zdir->filename_length - 6);
+ class_name [zdir->filename_length - 6] = '\0';
+ for (j = 0; class_name[j]; ++j)
+ class_name[j] = class_name[j] == '/' ? '.' : class_name[j];
+ return class_name;
+}
+
+/* Return 0 if we should skip this entry, 1 if it is a .class file, 2
+ if it is a property file of some sort. */
+static int
+classify_zip_file (struct ZipDirectory *zdir)
+{
+ char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
+
+ if (zdir->filename_length > 6
+ && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
+ ".class", 6))
+ return 1;
+
+ /* For now we drop the manifest and other information. Maybe it
+ would make more sense to compile it in? */
+ if (zdir->filename_length > 8
+ && !strncmp (class_name_in_zip_dir, "META-INF/", 9))
+ return 0;
+
+ /* Drop directory entries. */
+ if (zdir->filename_length > 0
+ && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
+ return 0;
+
+ return 2;
}
/* Process all class entries found in the zip file. */
@@ -1113,35 +1160,80 @@ parse_zip_file_entries (void)
i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
{
tree class;
-
- /* We don't need to consider those files. */
- if (!zdir->size || !zdir->filename_offset)
- continue;
-
- class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir)));
- current_jcf = TYPE_JCF (class);
- current_class = class;
- if ( !CLASS_LOADED_P (class))
+ switch (classify_zip_file (zdir))
{
- if (! CLASS_PARSED_P (class))
- {
- read_zip_member(current_jcf, zdir, localToFile);
- jcf_parse (current_jcf);
- }
- layout_class (current_class);
- load_inner_classes (current_class);
- }
+ case 0:
+ continue;
- if (TYPE_SIZE (current_class) != error_mark_node)
- {
- input_filename = current_jcf->filename;
- parse_class_file ();
- FREE (current_jcf->buffer); /* No longer necessary */
- /* Note: there is a way to free this buffer right after a
- class seen in a zip file has been parsed. The idea is the
- set its jcf in such a way that buffer will be reallocated
- the time the code for the class will be generated. FIXME. */
+ case 1:
+ {
+ char *class_name = compute_class_name (zdir);
+ class = lookup_class (get_identifier (class_name));
+ FREE (class_name);
+ current_jcf = TYPE_JCF (class);
+ current_class = class;
+
+ if (! CLASS_LOADED_P (class))
+ {
+ if (! CLASS_PARSED_P (class))
+ {
+ read_zip_member (current_jcf, zdir, localToFile);
+ jcf_parse (current_jcf);
+ }
+ layout_class (current_class);
+ load_inner_classes (current_class);
+ }
+
+ if (TYPE_SIZE (current_class) != error_mark_node)
+ {
+ input_filename = current_jcf->filename;
+ parse_class_file ();
+ FREE (current_jcf->buffer); /* No longer necessary */
+ /* Note: there is a way to free this buffer right after a
+ class seen in a zip file has been parsed. The idea is the
+ set its jcf in such a way that buffer will be reallocated
+ the time the code for the class will be generated. FIXME. */
+ }
+ }
+ break;
+
+ case 2:
+ {
+ char *file_name, *class_name_in_zip_dir, *buffer;
+ JCF *jcf;
+ file_name = ALLOC (zdir->filename_length + 1);
+ class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
+ strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
+ file_name[zdir->filename_length] = '\0';
+ jcf = ALLOC (sizeof (JCF));
+ JCF_ZERO (jcf);
+ jcf->read_state = finput;
+ jcf->filbuf = jcf_filbuf_from_stdio;
+ jcf->java_source = 0;
+ jcf->classname = NULL;
+ jcf->filename = file_name;
+ jcf->zipd = zdir;
+
+ if (read_zip_member (jcf, zdir, localToFile) < 0)
+ fatal_error ("error while reading %s from zip file", file_name);
+
+ buffer = ALLOC (zdir->filename_length + 1 +
+ (jcf->buffer_end - jcf->buffer));
+ strcpy (buffer, file_name);
+ memcpy (buffer + zdir->filename_length + 1,
+ jcf->buffer, jcf->buffer_end - jcf->buffer);
+
+ compile_resource_data (file_name, buffer,
+ jcf->buffer_end - jcf->buffer);
+ JCF_FINISH (jcf);
+ FREE (jcf);
+ FREE (buffer);
+ }
+ break;
+
+ default:
+ abort ();
}
}
}
@@ -1165,33 +1257,18 @@ process_zip_dir (FILE *finput)
class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
- /* We choose to not to process entries with a zero size or entries
- not bearing the .class extension. */
- if (!zdir->size || !zdir->filename_offset ||
- strncmp (&class_name_in_zip_dir[zdir->filename_length-6],
- ".class", 6))
- {
- /* So it will be skipped in parse_zip_file_entries */
- zdir->size = 0;
- continue;
- }
+ /* Here we skip non-class files; we handle them later. */
+ if (classify_zip_file (zdir) != 1)
+ continue;
- class_name = ALLOC (zdir->filename_length+1-6);
+ class_name = compute_class_name (zdir);
file_name = ALLOC (zdir->filename_length+1);
jcf = ggc_alloc (sizeof (JCF));
JCF_ZERO (jcf);
- strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);
- class_name [zdir->filename_length-6] = '\0';
strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
file_name [zdir->filename_length] = '\0';
- for (j=0; class_name[j]; j++)
- class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]);
-
- /* Yes, we write back the true class name into the zip directory. */
- strcpy (class_name_in_zip_dir, class_name);
- zdir->filename_length = j;
class = lookup_class (get_identifier (class_name));
jcf->read_state = finput;
diff --git a/gcc/java/resource.c b/gcc/java/resource.c
new file mode 100644
index 00000000000..3362cc89322
--- /dev/null
+++ b/gcc/java/resource.c
@@ -0,0 +1,199 @@
+/* Functions related to building resource files.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "flags.h"
+#include "java-tree.h"
+#include "jcf.h"
+#include "obstack.h"
+#include "toplev.h"
+#include "output.h"
+#include "parse.h"
+#include "function.h"
+#include "ggc.h"
+#include "stdio.h"
+#include "target.h"
+
+/* DOS brain-damage */
+#ifndef O_BINARY
+#define O_BINARY 0 /* MS-DOS brain-damage */
+#endif
+
+/* A list of all the resources files. */
+static GTY(()) tree resources = NULL;
+
+/* Function used to register resources. */
+static GTY(()) rtx registerResource_libfunc;
+
+/* Count of all the resources compiled in this invocation. */
+static int Jr_count = 0;
+
+void
+compile_resource_data (name, buffer, length)
+ char *name;
+ const char *buffer;
+ int length;
+{
+ tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
+ char buf[60];
+
+ data_type = build_prim_array_type (unsigned_byte_type_node,
+ strlen (name) + length);
+ rtype = make_node (RECORD_TYPE);
+ PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
+ PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
+ PUSH_FIELD (rtype, field, "data", data_type);
+ FINISH_RECORD (rtype);
+ START_RECORD_CONSTRUCTOR (rinit, rtype);
+ PUSH_FIELD_VALUE (rinit, "name_length",
+ build_int_2 (strlen (name), 0));
+ PUSH_FIELD_VALUE (rinit, "resource_length",
+ build_int_2 (length, 0));
+ data = build_string (strlen(name) + length, buffer);
+ TREE_TYPE (data) = data_type;
+ PUSH_FIELD_VALUE (rinit, "data", data);
+ FINISH_RECORD_CONSTRUCTOR (rinit);
+ TREE_CONSTANT (rinit) = 1;
+
+ /* Generate a unique-enough identifier. */
+ sprintf (buf, "_Jr%d", ++Jr_count);
+
+ decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
+ TREE_STATIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ TREE_THIS_VOLATILE (decl) = 0;
+ DECL_INITIAL (decl) = rinit;
+ layout_decl (decl, 0);
+ pushdecl (decl);
+ rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
+ make_decl_rtl (decl, (char*) 0);
+ assemble_variable (decl, 1, 0, 0);
+
+ resources = tree_cons (NULL_TREE, decl, resources);
+}
+
+void
+write_resource_constructor ()
+{
+ tree init_name, init_type, init_decl;
+ tree iter;
+
+ /* Only do work if required. */
+ if (resources == NULL_TREE)
+ return;
+
+ init_name = get_file_function_name ('I');
+ init_type = build_function_type (void_type_node, end_params_node);
+
+ init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
+ SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
+ TREE_STATIC (init_decl) = 1;
+ current_function_decl = init_decl;
+ DECL_RESULT (init_decl) = build_decl (RESULT_DECL,
+ NULL_TREE, void_type_node);
+
+ /* It can be a static function as long as collect2 does not have
+ to scan the object file to find its ctor/dtor routine. */
+ TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
+
+ pushlevel (0);
+ make_decl_rtl (init_decl, NULL);
+ init_function_start (init_decl, input_filename, 0);
+ expand_function_start (init_decl, 0);
+
+ /* Write out entries in the same order in which they were defined. */
+ for (iter = nreverse (resources); iter != NULL_TREE;
+ iter = TREE_CHAIN (iter))
+ {
+ char *name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (iter)));
+ emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
+ gen_rtx (SYMBOL_REF, Pmode, name),
+ Pmode);
+ }
+
+ expand_function_end (input_filename, 0, 0);
+ poplevel (1, 0, 1);
+ {
+ /* Force generation, even with -O3 or deeper. Gross hack.
+ FIXME. */
+ int saved_flag = flag_inline_functions;
+ flag_inline_functions = 0;
+ rest_of_compilation (init_decl);
+ flag_inline_functions = saved_flag;
+ }
+ current_function_decl = NULL_TREE;
+ (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
+ DEFAULT_INIT_PRIORITY);
+}
+
+/* Generate a byte array representing the contents of FILENAME. The
+ array is assigned a unique local symbol. The array represents a
+ compiled Java resource, which is accessed by the runtime using
+ NAME. */
+void
+compile_resource_file (name, filename)
+ char *name;
+ const char *filename;
+{
+ struct stat stat_buf;
+ int fd;
+ char *buffer;
+
+ fd = open (filename, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ {
+ perror ("Failed to read resource file");
+ return;
+ }
+ if (fstat (fd, &stat_buf) != 0
+ || ! S_ISREG (stat_buf.st_mode))
+ {
+ perror ("Could not figure length of resource file");
+ return;
+ }
+ buffer = xmalloc (strlen (name) + stat_buf.st_size);
+ strcpy (buffer, name);
+ read (fd, buffer + strlen (name), stat_buf.st_size);
+ close (fd);
+
+ compile_resource_data (name, buffer, stat_buf.st_size);
+ write_resource_constructor ();
+}
+
+void
+init_resource_processing ()
+{
+ registerResource_libfunc =
+ gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterResource");
+}
+
+#include "gt-java-resource.h"