From 7ad6876a9f0dff76e33dab6c0b59102017e3531c Mon Sep 17 00:00:00 2001 From: green Date: Thu, 6 Sep 2001 22:22:44 +0000 Subject: [PATCH] * class.c (O_BINARY): Define if necessary. (registerResource_libfunc): Declare. (init_class_processing): Initilize registerResource_libfunc. (compile_resource_file): New function. * java-tree.h (resource_name): Declare. (compile_resource_file): Declare. * jcf-parse.c (yyparse): Handle compiling java resource files. * lang.c (java_decode_option): Handle -fcompile-resource option. * jvspec.c (lang_specific_driver): Handle -R flag for compiling resource files. * gcj.texi (Code Generation): Add documentation for -R flag. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45448 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/class.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/java/gcj.texi | 7 +++- gcc/java/java-tree.h | 6 +++ gcc/java/jcf-parse.c | 17 ++++++++ gcc/java/jvspec.c | 47 ++++++++++++++++++++- gcc/java/lang.c | 9 +++++ 6 files changed, 195 insertions(+), 3 deletions(-) diff --git a/gcc/java/class.c b/gcc/java/class.c index 6086fc0db76..516ff8a3840 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -38,8 +38,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #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 + static tree make_method_value PARAMS ((tree)); static tree build_java_method_type PARAMS ((tree, tree, int)); static int32 hashUtf8String PARAMS ((const char *, int)); @@ -53,6 +59,7 @@ static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *, struct hash_table *, hash_table_key)); static rtx registerClass_libfunc; +static rtx registerResource_libfunc; extern struct obstack permanent_obstack; struct obstack temporary_obstack; @@ -832,6 +839,109 @@ hashUtf8String (str, 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 (name, filename) + char *name; + 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); + /* DECL_EXTERNAL (init_decl) = 1;*/ + TREE_PUBLIC (init_decl) = 1; + 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; tree @@ -1995,6 +2105,8 @@ void init_class_processing () { registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass"); + registerResource_libfunc = + gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterResource"); ggc_add_tree_root (class_roots, sizeof (class_roots) / sizeof (tree)); fields_ident = get_identifier ("fields"); info_ident = get_identifier ("info"); diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi index 6a52fc64ca5..e4beb5e1938 100644 --- a/gcc/java/gcj.texi +++ b/gcc/java/gcj.texi @@ -167,7 +167,7 @@ in which case they will all be compiled. If you specify a option, all the input files will be compiled together, producing a single output file, named @var{FILENAME}. This is allowed even when using @code{-S} or @code{-c}, -but not when using @code{-C}. +but not when using @code{-C} or @code{-R}. (This is an extension beyond the what plain @code{gcc} allows.) (If more than one input file is specified, all must currently be @code{.java} files, though we hope to fix this.) @@ -337,6 +337,11 @@ using the @code{java.lang.System.getProperty} method. This option is used to tell @code{gcj} to generate bytecode (@file{.class} files) rather than object code. +@item -R @var{resource-name} +This option is used to tell @code{gcj} to compile the contents of a +given file to object code so it may be accessed at runtime with the core +protocol handler as @var{core:/resource-name}. + @item -d @var{directory} When used with @code{-C}, this causes all generated @file{.class} files to be put in the appropriate subdirectory of @var{directory}. By diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index ef4e0632b79..cb6c738942f 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -163,6 +163,12 @@ extern int flag_emit_xref; /* When doing xrefs, tell when not to fold. */ extern int do_not_fold; +/* Resource name. */ +extern char * resource_name; + +/* Compile a resource file. */ +void compile_resource_file PARAMS ((char *, char *)); + /* Turned to 1 if -Wall was encountered. See lang.c for their meanings. */ extern int flag_wall; extern int flag_redundant; diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 1247ece6caf..75e0a23c582 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -36,6 +36,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "parse.h" #include "ggc.h" #include "debug.h" +#include "assert.h" #ifdef HAVE_LOCALE_H #include @@ -1084,6 +1085,22 @@ yyparse () if (filename_count == 0) warning ("no input file specified"); + if (resource_name) + { + char *resource_filename; + + /* Only one resource file may be compiled at a time. */ + assert (TREE_CHAIN (current_file_list) == NULL); + + resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list)); + compile_resource_file (resource_name, resource_filename); + + java_expand_classes (); + if (!java_report_errors ()) + emit_register_classes (); + return 0; + } + current_jcf = main_jcf; current_file_list = nreverse (current_file_list); for (node = current_file_list; node; node = TREE_CHAIN (node)) diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c index 44342cf401a..fd6d08f58d3 100644 --- a/gcc/java/jvspec.c +++ b/gcc/java/jvspec.c @@ -1,4 +1,4 @@ - /* Specific flags and argument handling of the front-end of the +/* Specific flags and argument handling of the front-end of the GNU compiler for the Java(TM) language. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. @@ -42,6 +42,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #define ZIP_FILE_ARG (1<<5) /* True if this arg is @FILE - where FILE contains a list of filenames. */ #define INDIRECT_FILE_ARG (1<<6) +/* True if this arg is a resource file. */ +#define RESOURCE_FILE_ARG (1<<7) static char *find_spec_file PARAMS ((const char *)); @@ -59,6 +61,7 @@ const char jvgenmain_spec[] = %{v:-version} %{pg:-p} %{p}\ %{