From 546468116ecab0398f68c844cdc553ae886aad7d Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Mon, 19 Mar 2001 13:57:37 -0800 Subject: [PATCH] Fixes to process to command-line .class files in two passes. See ChangeLog. From-SVN: r40637 --- gcc/java/ChangeLog | 31 +++++++++- gcc/java/class.c | 2 +- gcc/java/java-tree.h | 12 +++- gcc/java/jcf-parse.c | 131 ++++++++++++++++++++++++------------------- gcc/java/jcf.h | 6 +- gcc/java/parse.y | 9 ++- gcc/java/zipfile.h | 2 +- 7 files changed, 122 insertions(+), 71 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index b5c1dcd3eab..77f98ca210d 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,9 +1,38 @@ +2001-03-19 Per Bothner + + Fixes to process to command-line .class files in two passes. + * java-tree.h (JAVA_FILE_P, CLASS_FILE_P, ZIP_FILE_P): New flags. + (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P): Rename to .. + (CLASS_FROM_CURRENTLY_COMPILED_P): ... because it is more general now. + * class.c (is_compiled_class): Fix for renamed flag. + * parse.y (maybe_create_class_interface_decl): Likewise. + * jcf-parse.c (yyparse): Also set if compiling .class files. + * jcf-parse.c (read_class); Read current_class. + (jcf_parse): Make static. + (load_inner_classes): New function, with code moved from jcf_parse, + because we need to inner classes after the command-line files are read. + (yyparse): Set finput to NULL when it doesn't need to be closed. + Reduce use of main_jcf (basically only for archive) and + use finput instead of main_jcf->read_state. + Inline jcf_figure_file_type into yyparse. + Set JAVA_FILE_P, CLASS_FILE_P, or ZIP_FILE_P on filename list name. + Defer load_inner_classes and parse_class_file to a second pass, + after we've correctly mapped command-line .clas fiels to classes. + (jcf_figure_file_type): Removed. + * jcf.h (JCF_ZIP, JCF_CLASS, JCF_SOURCE): Removed flags. + (JCF_ZERO): Also clear zipd field. + * zipfile.h: Conditionalize on JCF_H insread of JCF_ZIP. + +2001-03-18 Matt Kraai + + * jcf-parse.c (yyparse): Change ch from char * to char. + 2001-03-19 Per Bothner * jvspec.c (lang_specific_driver): Check for .zip and .jar files. Add constructed filelist-file at end, following -xjava. Thus any .o and library files are not affected by the -xjava. Also wrap - explicut @FILE with -xjava and -xnone. + explicit @FILE with -xjava and -xnone. 2001-03-19 Andrew Haley diff --git a/gcc/java/class.c b/gcc/java/class.c index 6fc4cace43d..4114271e07d 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -1527,7 +1527,7 @@ is_compiled_class (class) return 2; seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class))); - if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip) + if (CLASS_FROM_CURRENTLY_COMPILED_P (class) || seen_in_zip) { /* The class was seen in the current ZIP file and will be available as a compiled class in the future but may not have diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index a2be1b3ef54..8dd98ba487f 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -49,14 +49,17 @@ struct JCF; COMPOUND_ASSIGN_P (in EXPR (binop_*)) LOCAL_CLASS_P (in RECORD_TYPE) BLOCK_IS_IMPLICIT (in BLOCK) + JAVA_FILE_P (in TREE_LIST in current_file_list) 2: RETURN_MAP_ADJUSTED (in TREE_VEC). QUALIFIED_P (in IDENTIFIER_NODE) PRIMARY_P (in EXPR_WITH_FILE_LOCATION) MODIFY_EXPR_FROM_INITIALIZATION_P (in MODIFY_EXPR) CLASS_METHOD_CHECKED_P (in RECORD_TYPE) + CLASS_FILE_P (in TREE_LIST in current_file_list) 3: IS_AN_IMPORT_ON_DEMAND_P (in IDENTIFIER_NODE) RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION) SWITCH_HAS_DEFAULT (in SWITCH_EXPR) + ZIP_FILE_P (in TREE_LIST in current_file_list) 4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE) RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION) CALL_USING_SUPER (in CALL_EXPR) @@ -947,7 +950,6 @@ extern tree get_constant PARAMS ((struct JCF*, int)); extern tree get_name_constant PARAMS ((struct JCF*, int)); extern tree get_class_constant PARAMS ((struct JCF*, int)); extern tree parse_signature PARAMS ((struct JCF *jcf, int sig_index)); -extern void jcf_parse PARAMS ((struct JCF*)); extern tree add_field PARAMS ((tree, tree, tree, int)); extern tree add_method PARAMS ((tree, int, tree, tree)); extern tree add_method_1 PARAMS ((tree, int, tree, tree)); @@ -1138,6 +1140,10 @@ struct rtx_def * java_lang_expand_expr PARAMS ((tree, rtx, enum machine_mode, #define METHOD_ABSTRACT(DECL) DECL_LANG_FLAG_5 (DECL) #define METHOD_TRANSIENT(DECL) DECL_LANG_FLAG_6 (DECL) +#define JAVA_FILE_P(NODE) TREE_LANG_FLAG_2 (NODE) +#define CLASS_FILE_P(NODE) TREE_LANG_FLAG_3 (NODE) +#define ZIP_FILE_P(NODE) TREE_LANG_FLAG_4 (NODE) + /* Other predicates on method decls */ #define DECL_CONSTRUCTOR_P(DECL) DECL_LANG_FLAG_7(DECL) @@ -1291,8 +1297,8 @@ extern tree *type_map; /* True of a RECORD_TYPE of a class/interface type (not array type) */ #define CLASS_P(TYPE) TYPE_LANG_FLAG_4 (TYPE) -/* True if class TYPE was defined in a Java source file compiled. */ -#define CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P(TYPE) \ +/* True if class TYPE was requested (on command line) to be compiled.*/ +#define CLASS_FROM_CURRENTLY_COMPILED_P(TYPE) \ TYPE_LANG_FLAG_5 (TYPE) /* True if class TYPE is currently being laid out. Helps in detection diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index b7a4c0b95f2..84f268878cb 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -81,9 +81,11 @@ static tree parse_roots[3] = { NULL_TREE, NULL_TREE, NULL_TREE }; /* A list of file names. */ #define current_file_list parse_roots[2] -/* The Java .class file that provides main_class; the main input file. */ +/* The Java archive that provides main_class; the main input file. */ static struct JCF main_jcf[1]; +static struct ZipFile *localToFile; + /* Declarations of some functions used here. */ static void handle_innerclass_attribute PARAMS ((int count, JCF *)); static tree give_name_to_class PARAMS ((JCF *jcf, int index)); @@ -92,11 +94,12 @@ static void process_zip_dir PARAMS ((FILE *)); static void parse_source_file_1 PARAMS ((tree, FILE *)); static void parse_source_file_2 PARAMS ((void)); static void jcf_parse_source PARAMS ((void)); -static int jcf_figure_file_type PARAMS ((JCF *)); static void parse_class_file PARAMS ((void)); static void set_source_filename PARAMS ((JCF *, int)); static int predefined_filename_p PARAMS ((tree)); static void ggc_mark_jcf PARAMS ((void**)); +static void jcf_parse PARAMS ((struct JCF*)); +static void load_inner_classes PARAMS ((tree)); /* Mark (for garbage collection) all the tree nodes that are referenced from JCF's constant pool table. */ @@ -576,9 +579,11 @@ read_class (name) java_parser_context_save_global (); java_push_parser_context (); input_filename = current_jcf->filename; + current_class = class; if (JCF_SEEN_IN_ZIP (current_jcf)) read_zip_member(current_jcf, current_jcf->zipd, current_jcf->zipd->zipf); jcf_parse (current_jcf); + load_inner_classes (current_class); java_pop_parser_context (0); java_parser_context_restore_global (); } @@ -708,11 +713,17 @@ jcf_parse (jcf) if (current_class == object_type_node) layout_class_methods (object_type_node); else - all_class_list = tree_cons (NULL_TREE, + all_class_list = tree_cons (NULL_TREE, TYPE_NAME (current_class), all_class_list ); +} - /* And if we came across inner classes, load them now. */ - for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (current_class)); current; +/* If we came across inner classes, load them now. */ +static void +load_inner_classes (cur_class) + tree cur_class; +{ + tree current; + for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current; current = TREE_CHAIN (current)) { tree name = DECL_NAME (TREE_PURPOSE (current)); @@ -889,7 +900,7 @@ yyparse () int filename_count = 0; char *list, *next; tree node; - FILE *finput; + FILE *finput = NULL; if (flag_filelist_file) { @@ -923,6 +934,7 @@ yyparse () next += count; } fclose (finput); + finput = NULL; } else list = xstrdup (input_filename); @@ -931,7 +943,7 @@ yyparse () { for (next = list; ; ) { - char *ch = *next; + char ch = *next; if (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ' || ch == '&' /* FIXME */) { @@ -1017,6 +1029,8 @@ yyparse () current_file_list = nreverse (current_file_list); for (node = current_file_list; node; node = TREE_CHAIN (node)) { + unsigned char magic_string[4]; + uint32 magic; tree name = TREE_VALUE (node); /* Skip already parsed files */ @@ -1024,41 +1038,62 @@ yyparse () continue; /* Close previous descriptor, if any */ - if (main_jcf->read_state && fclose (main_jcf->read_state)) - fatal_io_error ("can't close %s", - main_jcf->filename ? main_jcf->filename : ""); + if (finput && fclose (finput)) + fatal_io_error ("can't close input file %s", main_input_filename); - /* Set jcf up and open a new file */ - JCF_ZERO (main_jcf); - main_jcf->read_state = fopen (IDENTIFIER_POINTER (name), "rb"); - if (main_jcf->read_state == NULL) + finput = fopen (IDENTIFIER_POINTER (name), "rb"); + if (finput == NULL) fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name)); - /* Set new input_filename and finput */ - finput = main_jcf->read_state; #ifdef IO_BUFFER_SIZE setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); #endif input_filename = IDENTIFIER_POINTER (name); - main_jcf->filbuf = jcf_filbuf_from_stdio; - switch (jcf_figure_file_type (current_jcf)) + /* Figure what kind of file we're dealing with */ + if (fread (magic_string, 1, 4, finput) != 4) + fatal_io_error ("Premature end of input file %s", + IDENTIFIER_POINTER (name)); + fseek (finput, 0L, SEEK_SET); + magic = GET_u4 (magic_string); + if (magic == 0xcafebabe) { - case JCF_ZIP: - parse_zip_file_entries (); - break; - case JCF_CLASS: + CLASS_FILE_P (node) = 1; + current_jcf = ALLOC (sizeof (JCF)); + JCF_ZERO (current_jcf); + current_jcf->read_state = finput; + current_jcf->filbuf = jcf_filbuf_from_stdio; jcf_parse (current_jcf); - parse_class_file (); - break; - case JCF_SOURCE: + TYPE_JCF (current_class) = current_jcf; + CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1; + TREE_PURPOSE (node) = current_class; + } + else if (magic == (JCF_u4)ZIPMAGIC) + { + ZIP_FILE_P (node) = 1; + JCF_ZERO (main_jcf); + main_jcf->read_state = finput; + main_jcf->filbuf = jcf_filbuf_from_stdio; + 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. */ + process_zip_dir (main_jcf->read_state); + parse_zip_file_entries (); + /* + for (each entry) + CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1; + */ + } + else + { + JAVA_FILE_P (node) = 1; java_push_parser_context (); java_parser_context_save_global (); parse_source_file_1 (name, finput); java_parser_context_restore_global (); java_pop_parser_context (1); - break; } } @@ -1067,6 +1102,17 @@ yyparse () input_filename = ctxp->filename; parse_source_file_2 (); } + for (node = current_file_list; node; node = TREE_CHAIN (node)) + { + input_filename = IDENTIFIER_POINTER (TREE_VALUE (node)); + if (CLASS_FILE_P (node)) + { + current_class = TREE_PURPOSE (node); + current_jcf = TYPE_JCF (current_class); + load_inner_classes (current_class); + parse_class_file (); + } + } input_filename = main_input_filename; java_expand_classes (); @@ -1075,8 +1121,6 @@ yyparse () return 0; } -static struct ZipFile *localToFile; - /* Process all class entries found in the zip file. */ static void parse_zip_file_entries (void) @@ -1101,6 +1145,7 @@ parse_zip_file_entries (void) { read_zip_member(current_jcf, zdir, localToFile); jcf_parse (current_jcf); + load_inner_classes (current_class); } if (TYPE_SIZE (current_class) != error_mark_node) @@ -1175,36 +1220,6 @@ process_zip_dir (FILE *finput) } } -/* Figure what kind of file we're dealing with */ -static int -DEFUN(jcf_figure_file_type, (jcf), - JCF *jcf) -{ - unsigned char magic_string[4]; - uint32 magic; - - if (fread (magic_string, 1, 4, jcf->read_state) != 4) - jcf_unexpected_eof (jcf, 4); - - fseek (jcf->read_state, 0L, SEEK_SET); - magic = GET_u4 (magic_string); - - if (magic == 0xcafebabe) - return JCF_CLASS; - - /* FIXME: is it a system file? */ - if (magic == (JCF_u4)ZIPMAGIC - && !open_in_zip (jcf, input_filename, NULL, 0)) - { - localToFile = SeenZipFiles; - /* Register all the class defined there. */ - process_zip_dir (jcf->read_state); - return JCF_ZIP; - } - - return JCF_SOURCE; -} - /* Initialization. */ void diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index 5bb53b05c46..6fb6c254dde 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -63,10 +63,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #define JCF_word JCF_u4 #endif -#define JCF_ZIP 1 -#define JCF_CLASS 2 -#define JCF_SOURCE 3 - struct JCF; typedef int (*jcf_filbuf_t) PARAMS ((struct JCF*, int needed)); @@ -157,7 +153,7 @@ typedef struct JCF { #define JCF_ZERO(JCF) \ ((JCF)->buffer = (JCF)->buffer_end = (JCF)->read_ptr = (JCF)->read_end = 0,\ (JCF)->read_state = 0, (JCF)->filename = (JCF)->classname = 0, \ - CPOOL_INIT(&(JCF)->cpool), (JCF)->java_source = 0) + CPOOL_INIT(&(JCF)->cpool), (JCF)->java_source = 0, (JCF)->zipd = 0) /* Given that PTR points to a 2-byte unsigned integer in network (big-endian) byte-order, return that integer. */ diff --git a/gcc/java/parse.y b/gcc/java/parse.y index f36c4decf35..8d588f0f10a 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -3635,7 +3635,7 @@ maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl) else DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl); CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1; - CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) = + CLASS_FROM_CURRENTLY_COMPILED_P (TREE_TYPE (decl)) = IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl)); PUSH_CPC (decl, raw_name); @@ -5274,7 +5274,12 @@ jdep_resolve_class (dep) if (!decl) complete_class_report_errors (dep); else if (PURE_INNER_CLASS_DECL_P (decl)) - check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep)); + { + tree inner = TREE_TYPE (decl); + if (! CLASS_LOADED_P (inner)) + safe_layout_class (inner); + check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep)); + } return decl; } diff --git a/gcc/java/zipfile.h b/gcc/java/zipfile.h index f0be3cca4ec..e30fdda3832 100644 --- a/gcc/java/zipfile.h +++ b/gcc/java/zipfile.h @@ -60,7 +60,7 @@ extern struct ZipFile *SeenZipFiles; extern ZipFile * opendir_in_zip PARAMS ((const char *, int)); extern int read_zip_archive PARAMS ((ZipFile *)); -#ifdef JCF_ZIP +#ifdef JCF_H extern int read_zip_member PARAMS ((JCF*, ZipDirectory*, ZipFile *)); extern int open_in_zip PARAMS ((struct JCF *, const char *, const char *, int)); -- 2.30.2