#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));
struct hash_table *,
hash_table_key));
static rtx registerClass_libfunc;
+static rtx registerResource_libfunc;
extern struct obstack permanent_obstack;
struct obstack temporary_obstack;
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
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");
- /* 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.
#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 *));
%{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}\
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;
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')
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;
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;
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)
{