diff options
author | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-06 22:22:44 +0000 |
---|---|---|
committer | green <green@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-06 22:22:44 +0000 |
commit | 7ad6876a9f0dff76e33dab6c0b59102017e3531c (patch) | |
tree | 37aff30da6021cca7b3d351d0edb6a2570cbf393 /gcc/java | |
parent | 2a9870bd4c21a53bb1fad26248764444e0d67585 (diff) | |
download | gcc-7ad6876a9f0dff76e33dab6c0b59102017e3531c.tar.gz |
* 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
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/class.c | 112 | ||||
-rw-r--r-- | gcc/java/gcj.texi | 7 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 6 | ||||
-rw-r--r-- | gcc/java/jcf-parse.c | 17 | ||||
-rw-r--r-- | gcc/java/jvspec.c | 47 | ||||
-rw-r--r-- | 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 <locale.h> @@ -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}\ %{<fbounds-check} %{<fno-bounds-check}\ %{<fassume-compiled} %{<fno-assume-compiled}\ + %{<fcompile-resource*}\ %{<femit-class-file} %{<femit-class-files} %{<fencoding*}\ %{<fuse-boehm-gc} %{<fhash-synchronization} %{<fjni}\ %{<fclasspath*} %{<fCLASSPATH*} %{<foutput-class-dir}\ @@ -164,7 +167,8 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) int saw_libgcj ATTRIBUTE_UNUSED = 0; #endif - /* Saw -C or -o option, respectively. */ + /* Saw -R, -C or -o options, respectively. */ + int saw_R = 0; int saw_C = 0; int saw_o = 0; @@ -256,6 +260,16 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) library = 0; will_link = 0; } + else if (strcmp (argv[i], "-R") == 0) + { + saw_R = 1; + quote = argv[i]; + want_spec_file = 0; + if (library != 0) + added -= 2; + library = 0; + will_link = 0; + } else if (argv[i][1] == 'D') saw_D = 1; else if (argv[i][1] == 'g') @@ -324,6 +338,13 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) continue; } + if (saw_R) + { + args[i] |= RESOURCE_FILE_ARG; + last_input_index = i; + added += 2; /* for -xjava and -xnone */ + } + if (argv[i][0] == '@') { args[i] |= INDIRECT_FILE_ARG; @@ -362,6 +383,11 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) fatal ("can't specify `-D' without `--main'\n"); num_args = argc + added; + if (saw_R) + { + if (! saw_o) + fatal ("-R requires -o"); + } if (saw_C) { num_args += 3; @@ -434,6 +460,23 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) if ((args[i] & PARAM_ARG) || i == 0) continue; + if ((args[i] & RESOURCE_FILE_ARG) != 0) + { + arglist[j++] = "-xjava"; + arglist[j++] = argv[i]; + arglist[j] = "-xnone"; + } + + if (strcmp (argv[i], "-R") == 0) + { + char *ptr = argv[i+i]; + arglist[j] = concat ("-fcompile-resource=", + *argv[i+1] == '/' ? "" : "/", + argv[i+1], NULL); + i++; + continue; + } + if (strcmp (argv[i], "-classpath") == 0 || strcmp (argv[i], "-CLASSPATH") == 0) { diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 951d2996b30..abfdc885024 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -99,6 +99,8 @@ int compiling_from_source; const char * const language_string = "GNU Java"; +char * resource_name; + int flag_emit_class_files = 0; /* Nonzero if input file is a file with a list of filenames to compile. */ @@ -246,6 +248,13 @@ java_decode_option (argc, argv) return 0; } +#define CLARG "-fcompile-resource=" + if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0) + { + resource_name = p + sizeof (CLARG) - 1; + return 1; + } +#undef CLARG #define CLARG "-fassume-compiled=" if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0) { |