From a1b2d596c5e1b82621145fadb4714ec4d6a56701 Mon Sep 17 00:00:00 2001 From: aph Date: Thu, 10 Apr 2003 18:24:42 +0000 Subject: [PATCH] 2003-03-16 Mohan Embar * Make-lang.in: added win32-host.c * jcf.h: defined macro JCF_OPEN_EXACT_CASE which resolves to open() on non-Win32 platforms and Win32-specific jcf_open_exact_case() on Win32 * jcf-io.c (find_class): use JCF_OPEN_EXACT_CASE when trying .java and .class files * win32-host.c: added to repository. Defines Win32-specific jcf_open_exact_case() 2003-04-10 Andrew Haley * jcf-write.c (struct jcf_partial): num_jsrs: new field. (maybe_free_localvar): Renamed from localvar_free. Add new arg, really. (generate_bytecode_insns): Set new variable, jsrs. Only free local vars if no jsr insns have been emittted. Call maybe_free_localvar, not localvar_free. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65430 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 20 ++++++++++++ gcc/java/Make-lang.in | 1 + gcc/java/jcf-io.c | 4 +-- gcc/java/jcf-write.c | 25 ++++++++++----- gcc/java/jcf.h | 18 +++++++++++ gcc/java/win32-host.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 gcc/java/win32-host.c diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index c141615..85a30a9 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,23 @@ +2003-03-16 Mohan Embar + + * Make-lang.in: added win32-host.c + * jcf.h: defined macro JCF_OPEN_EXACT_CASE which + resolves to open() on non-Win32 platforms and + Win32-specific jcf_open_exact_case() on Win32 + * jcf-io.c (find_class): use JCF_OPEN_EXACT_CASE + when trying .java and .class files + * win32-host.c: added to repository. Defines + Win32-specific jcf_open_exact_case() + +2003-04-10 Andrew Haley + + * jcf-write.c (struct jcf_partial): num_jsrs: new field. + (maybe_free_localvar): Renamed from localvar_free. + Add new arg, really. + (generate_bytecode_insns): Set new variable, jsrs. + Only free local vars if no jsr insns have been emittted. + Call maybe_free_localvar, not localvar_free. + 2003-03-30 Joseph S. Myers * gcj.texi: Remove @ at start of file. diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index 9a97da5..5d74714 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -334,6 +334,7 @@ java/resource.o: java/resource.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TARGET_H) function.h gt-java-resource.h java/typeck.o: java/typeck.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \ java/convert.h toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) real.h +java/win32-host.o: java/win32-host.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h java/verify.o: java/verify.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \ java/javaop.h java/java-opcodes.h java/java-except.h toplev.h $(SYSTEM_H) \ coretypes.h $(TM_H) diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c index c280f1f..d673ec8 100644 --- a/gcc/java/jcf-io.c +++ b/gcc/java/jcf-io.c @@ -544,7 +544,7 @@ find_class (const char *classname, int classname_length, JCF *jcf, classname+classname_length- (classname_length <= 30 ? classname_length : 30))); - fd = open (buffer, O_RDONLY | O_BINARY); + fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY | O_BINARY); if (fd >= 0) goto found; } @@ -556,7 +556,7 @@ find_class (const char *classname, int classname_length, JCF *jcf, classname+classname_length- (classname_length <= 30 ? classname_length : 30))); - fd = open (buffer, O_RDONLY); + fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY); if (fd >= 0) { jcf->java_source = 1; diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index d9fc650..9c05a5a 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -279,6 +279,9 @@ struct jcf_partial /* Information about the current switch statement. */ struct jcf_switch_state *sw_state; + + /* The count of jsr instructions that have been emmitted. */ + long num_jsrs; }; static void generate_bytecode_insns (tree, int, struct jcf_partial *); @@ -293,7 +296,7 @@ static void define_jcf_label (struct jcf_block *, struct jcf_partial *); static struct jcf_block * get_jcf_label_here (struct jcf_partial *); static void put_linenumber (int, struct jcf_partial *); static void localvar_alloc (tree, struct jcf_partial *); -static void localvar_free (tree, struct jcf_partial *); +static void maybe_free_localvar (tree, struct jcf_partial *, int); static int get_access_flags (tree); static void write_chunks (FILE *, struct chunk *); static int adjust_typed_op (tree, int); @@ -601,7 +604,7 @@ localvar_alloc (tree decl, struct jcf_partial *state) } static void -localvar_free (tree decl, struct jcf_partial *state) +maybe_free_localvar (tree decl, struct jcf_partial *state, int really) { struct jcf_block *end_label = get_jcf_label_here (state); int index = DECL_LOCAL_INDEX (decl); @@ -613,6 +616,8 @@ localvar_free (tree decl, struct jcf_partial *state) if (info->decl != decl) abort (); + if (! really) + return; ptr[0] = NULL; if (wide) { @@ -1066,6 +1071,7 @@ emit_jsr (struct jcf_block *target, struct jcf_partial *state) OP1 (OPCODE_jsr); /* Value is 1 byte from reloc back to start of instruction. */ emit_reloc (RELOCATION_VALUE_1, OPCODE_jsr_w, target, state); + state->num_jsrs++; } /* Generate code to evaluate EXP. If the result is true, @@ -1347,7 +1353,7 @@ generate_bytecode_return (tree exp, struct jcf_partial *state) emit_store (state->return_value_decl, state); call_cleanups (NULL, state); emit_load (state->return_value_decl, state); - /* If we call localvar_free (state->return_value_decl, state), + /* If we call maybe_free_localvar (state->return_value_decl, state, 1), then we risk the save decl erroneously re-used in the finalizer. Instead, we keep the state->return_value_decl allocated through the rest of the method. This is not @@ -1384,6 +1390,7 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) { tree local; tree body = BLOCK_EXPR_BODY (exp); + long jsrs = state->num_jsrs; for (local = BLOCK_EXPR_DECLS (exp); local; ) { tree next = TREE_CHAIN (local); @@ -1397,10 +1404,11 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) body = TREE_OPERAND (body, 1); } generate_bytecode_insns (body, target, state); + for (local = BLOCK_EXPR_DECLS (exp); local; ) { tree next = TREE_CHAIN (local); - localvar_free (local, state); + maybe_free_localvar (local, state, state->num_jsrs <= jsrs); local = next; } } @@ -2354,8 +2362,8 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) if (CAN_COMPLETE_NORMALLY (finally)) { maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state); - localvar_free (exception_decl, state); - localvar_free (return_link, state); + maybe_free_localvar (exception_decl, state, 1); + maybe_free_localvar (return_link, state, 1); define_jcf_label (finished_label, state); } } @@ -2960,6 +2968,7 @@ generate_classfile (tree clas, struct jcf_partial *state) get_jcf_label_here (state); /* Force a first block. */ for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t)) localvar_alloc (t, state); + state->num_jsrs = 0; generate_bytecode_insns (body, IGNORE_TARGET, state); if (CAN_COMPLETE_NORMALLY (body)) { @@ -2969,9 +2978,9 @@ generate_classfile (tree clas, struct jcf_partial *state) OP1 (OPCODE_return); } for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t)) - localvar_free (t, state); + maybe_free_localvar (t, state, 1); if (state->return_value_decl != NULL_TREE) - localvar_free (state->return_value_decl, state); + maybe_free_localvar (state->return_value_decl, state, 1); finish_jcf_block (state); perform_relocations (state); diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index 9680974..5a28735 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -63,6 +63,24 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #define COMPARE_FILENAMES(X, Y) strcmp ((X), (Y)) #endif +/* On case-insensitive file systems, we need to ensure that a request + to open a .java or .class file is honored only if the file to be + opened is of the exact case we are asking for. In other words, we + want to override the inherent case insensitivity of the underlying + file system. On other platforms, this macro becomes the vanilla + open() call. + + If you want to add another host, add your define to the list below + (i.e. defined(WIN32) || defined(YOUR_HOST)) and add an host-specific + .c file to Make-lang.in similar to win32-host.c */ +#if defined(WIN32) +extern int +jcf_open_exact_case (const char* filename, int oflag); +#define JCF_OPEN_EXACT_CASE(X, Y) jcf_open_exact_case (X, Y) +#else +#define JCF_OPEN_EXACT_CASE open +#endif /* WIN32 */ + struct JCF; typedef int (*jcf_filbuf_t) PARAMS ((struct JCF*, int needed)); diff --git a/gcc/java/win32-host.c b/gcc/java/win32-host.c new file mode 100644 index 0000000..7ab8fa5 --- /dev/null +++ b/gcc/java/win32-host.c @@ -0,0 +1,85 @@ +/* Platform-Specific Win32 Functions + Copyright (C) 2003 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + +Java and all Java-based marks are trademarks or registered trademarks +of Sun Microsystems, Inc. in the United States and other countries. +The Free Software Foundation is independent of Sun Microsystems, Inc. */ + +/* Written by Mohan Embar , March 2003. */ + +#ifdef WIN32 + +#include "config.h" +#include "system.h" + +#include "jcf.h" + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +/* Simulate an open() failure with ENOENT */ +static int +file_not_found (void); + +static int +file_not_found (void) +{ + errno = ENOENT; + return -1; +} + +int +jcf_open_exact_case (const char *filename, int oflag) +{ + int filename_len = strlen (filename); + int found_file_len; + HANDLE found_file_handle; + WIN32_FIND_DATA fd; + + /* See if we can find this file. */ + found_file_handle = FindFirstFile (filename, &fd); + if (found_file_handle == INVALID_HANDLE_VALUE) + return file_not_found (); + FindClose (found_file_handle); + + found_file_len = strlen (fd.cFileName); + + /* This should never happen. */ + if (found_file_len > filename_len) + return file_not_found (); + + /* Here, we're only actually comparing the filename and not + checking the case of any containing directory components. + Although we're not fully obeying our contract, checking + all directory components would be tedious and time-consuming + and it's a pretty safe assumption that mixed-case package + names are a fringe case.... */ + if (strcmp (filename + filename_len - found_file_len, fd.cFileName)) + { + /* Reject this because it is not a perfect-case match. */ + /* printf("************\nRejected:\n%s\n%s\n************\n\n", filename, fd.cFileName); */ + return file_not_found (); + } + else + { + return open (filename, oflag); + } +} + +#endif /* WIN32 */ -- 2.7.4