Commit 7be5b0e5 by Anthony Green

class.c (O_BINARY): Define if necessary.

        * 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.

From-SVN: r45448
parent 7d8be4da
......@@ -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");
......
......@@ -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
......
......@@ -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;
......
......@@ -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))
......
/* 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)
{
......
......@@ -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)
{
......
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